@untangle-code/file-graph 0.0.0-stage → 0.1.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.
Files changed (130) hide show
  1. package/LICENSE +661 -0
  2. package/NOTICE +90 -0
  3. package/README.md +284 -2
  4. package/THIRD_PARTY_LICENSES.md +29 -0
  5. package/dist/assignment.d.ts +15 -0
  6. package/dist/assignment.d.ts.map +1 -0
  7. package/dist/assignment.js +75 -0
  8. package/dist/assignment.js.map +1 -0
  9. package/dist/boundaries/endpoints.d.ts +11 -0
  10. package/dist/boundaries/endpoints.d.ts.map +1 -0
  11. package/dist/boundaries/endpoints.js +195 -0
  12. package/dist/boundaries/endpoints.js.map +1 -0
  13. package/dist/boundaries/index.d.ts +9 -0
  14. package/dist/boundaries/index.d.ts.map +1 -0
  15. package/dist/boundaries/index.js +93 -0
  16. package/dist/boundaries/index.js.map +1 -0
  17. package/dist/boundaries/requests.d.ts +12 -0
  18. package/dist/boundaries/requests.d.ts.map +1 -0
  19. package/dist/boundaries/requests.js +311 -0
  20. package/dist/boundaries/requests.js.map +1 -0
  21. package/dist/edges.d.ts +49 -0
  22. package/dist/edges.d.ts.map +1 -0
  23. package/dist/edges.js +223 -0
  24. package/dist/edges.js.map +1 -0
  25. package/dist/file-index.d.ts +37 -0
  26. package/dist/file-index.d.ts.map +1 -0
  27. package/dist/file-index.js +103 -0
  28. package/dist/file-index.js.map +1 -0
  29. package/dist/graph.d.ts +160 -0
  30. package/dist/graph.d.ts.map +1 -0
  31. package/dist/graph.js +448 -0
  32. package/dist/graph.js.map +1 -0
  33. package/dist/index.d.ts +35 -0
  34. package/dist/index.d.ts.map +1 -0
  35. package/dist/index.js +48 -0
  36. package/dist/index.js.map +1 -0
  37. package/dist/metrics.d.ts +67 -0
  38. package/dist/metrics.d.ts.map +1 -0
  39. package/dist/metrics.js +272 -0
  40. package/dist/metrics.js.map +1 -0
  41. package/dist/package-catalog.d.ts +43 -0
  42. package/dist/package-catalog.d.ts.map +1 -0
  43. package/dist/package-catalog.js +136 -0
  44. package/dist/package-catalog.js.map +1 -0
  45. package/dist/paths.d.ts +56 -0
  46. package/dist/paths.d.ts.map +1 -0
  47. package/dist/paths.js +129 -0
  48. package/dist/paths.js.map +1 -0
  49. package/dist/persistence.d.ts +83 -0
  50. package/dist/persistence.d.ts.map +1 -0
  51. package/dist/persistence.js +538 -0
  52. package/dist/persistence.js.map +1 -0
  53. package/dist/resolve/candidates.d.ts +52 -0
  54. package/dist/resolve/candidates.d.ts.map +1 -0
  55. package/dist/resolve/candidates.js +202 -0
  56. package/dist/resolve/candidates.js.map +1 -0
  57. package/dist/resolve/package-exports.d.ts +31 -0
  58. package/dist/resolve/package-exports.d.ts.map +1 -0
  59. package/dist/resolve/package-exports.js +229 -0
  60. package/dist/resolve/package-exports.js.map +1 -0
  61. package/dist/resolve/pipeline.d.ts +11 -0
  62. package/dist/resolve/pipeline.d.ts.map +1 -0
  63. package/dist/resolve/pipeline.js +109 -0
  64. package/dist/resolve/pipeline.js.map +1 -0
  65. package/dist/resolve/resolvers.d.ts +25 -0
  66. package/dist/resolve/resolvers.d.ts.map +1 -0
  67. package/dist/resolve/resolvers.js +367 -0
  68. package/dist/resolve/resolvers.js.map +1 -0
  69. package/dist/restore.d.ts +75 -0
  70. package/dist/restore.d.ts.map +1 -0
  71. package/dist/restore.js +136 -0
  72. package/dist/restore.js.map +1 -0
  73. package/dist/topology/compose.d.ts +27 -0
  74. package/dist/topology/compose.d.ts.map +1 -0
  75. package/dist/topology/compose.js +208 -0
  76. package/dist/topology/compose.js.map +1 -0
  77. package/dist/topology/jsonc.d.ts +38 -0
  78. package/dist/topology/jsonc.d.ts.map +1 -0
  79. package/dist/topology/jsonc.js +137 -0
  80. package/dist/topology/jsonc.js.map +1 -0
  81. package/dist/topology/load.d.ts +61 -0
  82. package/dist/topology/load.d.ts.map +1 -0
  83. package/dist/topology/load.js +436 -0
  84. package/dist/topology/load.js.map +1 -0
  85. package/dist/topology/manifest.d.ts +48 -0
  86. package/dist/topology/manifest.d.ts.map +1 -0
  87. package/dist/topology/manifest.js +109 -0
  88. package/dist/topology/manifest.js.map +1 -0
  89. package/dist/topology/project-config.d.ts +39 -0
  90. package/dist/topology/project-config.d.ts.map +1 -0
  91. package/dist/topology/project-config.js +150 -0
  92. package/dist/topology/project-config.js.map +1 -0
  93. package/dist/topology/workspace-definition.d.ts +26 -0
  94. package/dist/topology/workspace-definition.d.ts.map +1 -0
  95. package/dist/topology/workspace-definition.js +104 -0
  96. package/dist/topology/workspace-definition.js.map +1 -0
  97. package/dist/traverse.d.ts +49 -0
  98. package/dist/traverse.d.ts.map +1 -0
  99. package/dist/traverse.js +167 -0
  100. package/dist/traverse.js.map +1 -0
  101. package/dist/types.d.ts +332 -0
  102. package/dist/types.d.ts.map +1 -0
  103. package/dist/types.js +2 -0
  104. package/dist/types.js.map +1 -0
  105. package/package.json +63 -3
  106. package/src/assignment.ts +83 -0
  107. package/src/boundaries/endpoints.ts +273 -0
  108. package/src/boundaries/index.ts +118 -0
  109. package/src/boundaries/requests.ts +411 -0
  110. package/src/edges.ts +334 -0
  111. package/src/file-index.ts +127 -0
  112. package/src/graph.ts +591 -0
  113. package/src/index.ts +58 -0
  114. package/src/metrics.ts +350 -0
  115. package/src/package-catalog.ts +145 -0
  116. package/src/paths.ts +138 -0
  117. package/src/persistence.ts +746 -0
  118. package/src/resolve/candidates.ts +230 -0
  119. package/src/resolve/package-exports.ts +268 -0
  120. package/src/resolve/pipeline.ts +140 -0
  121. package/src/resolve/resolvers.ts +468 -0
  122. package/src/restore.ts +201 -0
  123. package/src/topology/compose.ts +268 -0
  124. package/src/topology/jsonc.ts +147 -0
  125. package/src/topology/load.ts +644 -0
  126. package/src/topology/manifest.ts +132 -0
  127. package/src/topology/project-config.ts +183 -0
  128. package/src/topology/workspace-definition.ts +115 -0
  129. package/src/traverse.ts +232 -0
  130. package/src/types.ts +372 -0
package/dist/graph.js ADDED
@@ -0,0 +1,448 @@
1
+ import { buildSkipLedgerEntry, compareCodepoints, summarizeSkipReasons, uniqueSortedByCodepoints, } from "@untangle-code/domain";
2
+ import { assignContainerService, assignPackage } from "./assignment.js";
3
+ import { buildEdgesForFile, compareEdges } from "./edges.js";
4
+ import { FileIndex } from "./file-index.js";
5
+ import { DEFAULT_GRAPH_LIMITS, buildAdjacency, computeFileGraphMetrics } from "./metrics.js";
6
+ import { WorkspacePackageCatalog } from "./package-catalog.js";
7
+ import { basenameOf, dirnameOf, extensionOf, normalizePath } from "./paths.js";
8
+ import { DEFAULT_EXTENSION_ORDER } from "./resolve/candidates.js";
9
+ import { DEFAULT_TRAVERSAL_LIMITS, traverseFileGraph } from "./traverse.js";
10
+ /**
11
+ * Standardbudgets und Uhr leben seit dem Bau des Lesepfades in `traverse.ts`
12
+ * — hier stehen sie nur noch als Weiterreichung, damit der bisherige
13
+ * Einstiegspunkt des Pakets unveraendert bleibt.
14
+ */
15
+ export { DEFAULT_TRAVERSAL_LIMITS };
16
+ export class FileDependencyGraph {
17
+ workspaceId;
18
+ graphGeneration;
19
+ index;
20
+ edgeContext;
21
+ topology;
22
+ limits;
23
+ nodesById = new Map();
24
+ edgesById = new Map();
25
+ edgeIdsByFrom = new Map();
26
+ filesById = new Map();
27
+ /**
28
+ * Ledger-Eintraege JE DATEI statt in einer flachen Liste.
29
+ *
30
+ * Eine flache Liste laesst sich nur ueber den Pfad aufraeumen — und der ist
31
+ * genau das, was sich bei einer Umbenennung aendert. Ein Eintrag der alten
32
+ * Fassung bliebe dann unter dem ALTEN Pfad stehen, und beim Entfernen einer
33
+ * Datei bliebe er ganz. Beides sind Meldungen ueber Dateien, die der Graph
34
+ * nicht mehr kennt; `countsByReason` waere dauerhaft falsch. Ueber die
35
+ * `file_id` ist das Aufraeumen exakt.
36
+ */
37
+ skipEntriesByFile = new Map();
38
+ adjacency = { forward: new Map(), reverse: new Map() };
39
+ cachedMetrics = null;
40
+ constructor(workspaceId, graphGeneration, index, edgeContext, topology, limits) {
41
+ this.workspaceId = workspaceId;
42
+ this.graphGeneration = graphGeneration;
43
+ this.index = index;
44
+ this.edgeContext = edgeContext;
45
+ this.topology = topology;
46
+ this.limits = limits;
47
+ }
48
+ static build(input) {
49
+ const index = FileIndex.fromFiles(input.files);
50
+ const packages = input.topology.packages;
51
+ // Repository-bewusster Katalog: eine Karte nach Namen allein liesse
52
+ // gleichnamige Pakete zweier Repositories einander ersatzlos verdecken.
53
+ const packageCatalog = new WorkspacePackageCatalog(packages);
54
+ const refIdByRepoId = new Map(input.repositories.map((repository) => [repository.repoId, repository.refId]));
55
+ const edgeContext = {
56
+ workspaceId: input.workspaceId,
57
+ graphGeneration: input.graphGeneration,
58
+ packages,
59
+ packageCatalog,
60
+ services: input.topology.services,
61
+ projectAliases: input.projectAliases ?? [],
62
+ configuredAliases: input.configuredAliases ?? [],
63
+ extensionOrder: input.extensionOrder ?? DEFAULT_EXTENSION_ORDER,
64
+ files: index,
65
+ refIdByRepoId,
66
+ resolveFileId: (repoId, path) => index.fileIdOf(repoId, path),
67
+ ...(input.pipeline === undefined ? {} : { pipeline: input.pipeline }),
68
+ };
69
+ const graph = new FileDependencyGraph(input.workspaceId, input.graphGeneration, index, edgeContext, input.topology, { ...DEFAULT_GRAPH_LIMITS, ...input.limits });
70
+ for (const file of input.files) {
71
+ graph.filesById.set(file.fileId, file);
72
+ }
73
+ for (const file of [...input.files].sort((left, right) => compareCodepoints(left.fileId, right.fileId))) {
74
+ graph.rebuildEdgesOf(file);
75
+ }
76
+ graph.refresh();
77
+ return graph;
78
+ }
79
+ // -------------------------------------------------------------------------
80
+ // Abfragen
81
+ // -------------------------------------------------------------------------
82
+ nodes() {
83
+ return [...this.nodesById.values()].sort((left, right) => compareCodepoints(left.fileId, right.fileId));
84
+ }
85
+ edges() {
86
+ return [...this.edgesById.values()].sort(compareEdges);
87
+ }
88
+ node(fileId) {
89
+ return this.nodesById.get(fileId) ?? null;
90
+ }
91
+ edge(edgeId) {
92
+ return this.edgesById.get(edgeId) ?? null;
93
+ }
94
+ /** Kanten, deren Quelle `fileId` ist, in kanonischer Ordnung. */
95
+ edgesFrom(fileId) {
96
+ return (this.edgeIdsByFrom.get(fileId) ?? [])
97
+ .map((edgeId) => this.edgesById.get(edgeId))
98
+ .filter((edge) => edge !== undefined)
99
+ .sort(compareEdges);
100
+ }
101
+ metrics() {
102
+ if (this.cachedMetrics === null) {
103
+ this.cachedMetrics = computeFileGraphMetrics({
104
+ workspaceId: this.workspaceId,
105
+ graphGeneration: this.graphGeneration,
106
+ nodes: this.nodes(),
107
+ edges: this.edges(),
108
+ adjacency: this.adjacency,
109
+ limits: this.limits,
110
+ });
111
+ }
112
+ return this.cachedMetrics;
113
+ }
114
+ /** Alle Ledger-Eintraege des Graphen, in kanonischer Ordnung. */
115
+ allSkipEntries() {
116
+ const entries = [];
117
+ for (const fileId of [...this.skipEntriesByFile.keys()].sort(compareCodepoints)) {
118
+ entries.push(...(this.skipEntriesByFile.get(fileId) ?? []));
119
+ }
120
+ return entries;
121
+ }
122
+ skipLedger() {
123
+ const entries = sortSkipEntries(this.allSkipEntries());
124
+ return {
125
+ schemaVersion: 1,
126
+ generationId: this.graphGeneration,
127
+ entries,
128
+ countsByReason: summarizeSkipReasons(entries),
129
+ };
130
+ }
131
+ /** Vollstaendiges, serialisierbares Abbild inklusive Topologie und Ledger. */
132
+ snapshot() {
133
+ const graphEntries = sortSkipEntries([
134
+ ...this.allSkipEntries(),
135
+ ...this.topology.skipped.entries,
136
+ ]);
137
+ return {
138
+ schemaVersion: 1,
139
+ workspaceId: this.workspaceId,
140
+ graphGeneration: this.graphGeneration,
141
+ nodes: this.nodes(),
142
+ edges: this.edges(),
143
+ metrics: this.metrics(),
144
+ topology: this.topology,
145
+ skipped: {
146
+ schemaVersion: 1,
147
+ generationId: this.graphGeneration,
148
+ entries: graphEntries,
149
+ countsByReason: summarizeSkipReasons(graphEntries),
150
+ },
151
+ };
152
+ }
153
+ // -------------------------------------------------------------------------
154
+ // Traversierung
155
+ // -------------------------------------------------------------------------
156
+ /** Woran haenge ich (vorwaerts, ueber `dependencies`). */
157
+ dependenciesOf(fileId, limits, now) {
158
+ return this.traverse([fileId], {
159
+ direction: "forward",
160
+ ...(limits === undefined ? {} : { limits }),
161
+ ...(now === undefined ? {} : { now }),
162
+ });
163
+ }
164
+ /** Wer haengt an mir (rueckwaerts, ueber `dependents`) — die Wirkungsfrage. */
165
+ dependentsOf(fileId, limits, now) {
166
+ return this.traverse([fileId], {
167
+ direction: "reverse",
168
+ ...(limits === undefined ? {} : { limits }),
169
+ ...(now === undefined ? {} : { now }),
170
+ });
171
+ }
172
+ /**
173
+ * Tiefensuche mit Budget und Zyklenmeldung.
174
+ *
175
+ * Die Traversierung selbst steht in `traverse.ts` — sie ist wortgleich die,
176
+ * die auch ein aus einem Abbild zurueckgeladener Graph benutzt. Hier bleibt
177
+ * nur die Nachbarschaft: die Adjazenz dieses Graphen und die Frage, welche
178
+ * Kante zwei benachbarte Dateien verbindet.
179
+ */
180
+ traverse(rootFileIds, options) {
181
+ const neighborhood = {
182
+ adjacency: this.adjacency,
183
+ edgeIdBetween: (from, to, direction) => this.edgeIdBetween(from, to, direction),
184
+ };
185
+ return traverseFileGraph(neighborhood, rootFileIds, options);
186
+ }
187
+ // -------------------------------------------------------------------------
188
+ // Inkrementelle Fortschreibung
189
+ // -------------------------------------------------------------------------
190
+ /**
191
+ * Schreibt den Graphen fort, ohne ihn neu zu bauen.
192
+ *
193
+ * WELCHE DATEIEN NEU GERECHNET WERDEN — und warum nicht nur die geaenderte:
194
+ *
195
+ * - `modified` (Inhalt geaendert, Pfad gleich): NUR die Datei selbst. Ihre
196
+ * Existenz hat sich nicht geaendert, also kann sich die Aufloesung keiner
197
+ * anderen Datei geaendert haben.
198
+ * - `added` / `removed`: zusaetzlich jede Datei, deren Aufloesung von der
199
+ * Existenz dieses Pfades abhaengt. Die ist exakt bestimmbar, weil jede
200
+ * unaufgeloeste Kante ihre geprueften Kandidaten mitfuehrt (E4 zahlt sich
201
+ * hier aus): wer den betroffenen Pfad geprueft und nicht gefunden hat,
202
+ * findet ihn jetzt. Dazu kommen die bisherigen Abhaengigen und alle
203
+ * Dateien, die auf denselben Stamm aufgeloest haben (Verdeckungsfall:
204
+ * ein neues `util.ts` verdeckt ein bestehendes `util.js`).
205
+ */
206
+ applyChanges(changes) {
207
+ const previousEdgeIds = new Set(this.edgesById.keys());
208
+ const dependentsBefore = new Map([...this.adjacency.reverse.entries()].map(([id, sources]) => [id, sources.join("/")]));
209
+ const toRecompute = new Set();
210
+ const affectedPaths = [];
211
+ /**
212
+ * WP-195: Ein `removed` fuer eine `file_id`, die dieser Graph gar nicht
213
+ * kennt, verschwand bisher spurlos — `entryById` gab `null`, `dropFile`
214
+ * fand nichts, und der Aufrufer bekam ein Ergebnis, das aussah, als sei
215
+ * die Loeschung ausgefuehrt worden. Genau daran erkennt man aber, dass
216
+ * zwei Zustaende auseinandergelaufen sind: der Waechter meldet die
217
+ * Loeschung einer Datei, die der Graph nie hatte. Das ist ein Befund, kein
218
+ * Nichts.
219
+ */
220
+ const unknownRemovals = [];
221
+ for (const change of changes) {
222
+ if (change.kind === "removed") {
223
+ const entry = this.index.entryById(change.fileId);
224
+ if (entry !== null) {
225
+ affectedPaths.push({ repoId: entry.repoId, path: entry.path });
226
+ }
227
+ else {
228
+ unknownRemovals.push(change.fileId);
229
+ }
230
+ this.dropFile(change.fileId);
231
+ continue;
232
+ }
233
+ const file = change.file;
234
+ const nextPath = normalizePath(file.path);
235
+ const previous = this.index.entryById(file.fileId);
236
+ let pathChanged = false;
237
+ if (previous !== null && (previous.path !== nextPath || previous.repoId !== file.repoId)) {
238
+ // Ein Pfadwechsel ist fachlich ein Entfernen plus ein Hinzufuegen —
239
+ // und zwar BEIDES. Der alte Pfad verschwindet:
240
+ pathChanged = true;
241
+ affectedPaths.push({ repoId: previous.repoId, path: previous.path });
242
+ }
243
+ // ... und der neue Pfad entsteht. Nur die erste Haelfte zu melden war
244
+ // der Fehler: wer den neuen Pfad vergeblich geprueft hatte, findet ihn
245
+ // jetzt (A5), und wer auf denselben Stamm mit schwaecherer Endung
246
+ // aufgeloest hatte, wird jetzt verdeckt (A6). Beide Faelle blieben
247
+ // ungerechnet, das Ergebnis wich vom Neubau ab, und weil die Kante auf
248
+ // eine EXISTIERENDE Datei zeigte, meldete auch das Ledger nichts (E4).
249
+ if (change.kind === "added" || previous === null || pathChanged) {
250
+ affectedPaths.push({ repoId: file.repoId, path: nextPath });
251
+ }
252
+ this.filesById.set(file.fileId, file);
253
+ this.index.add({
254
+ fileId: file.fileId,
255
+ repoId: file.repoId,
256
+ refId: file.refId,
257
+ path: nextPath,
258
+ languageId: file.languageId,
259
+ contentHash: file.contentHash,
260
+ });
261
+ toRecompute.add(file.fileId);
262
+ }
263
+ for (const affected of affectedPaths) {
264
+ for (const fileId of this.filesDependingOnPath(affected.repoId, affected.path)) {
265
+ toRecompute.add(fileId);
266
+ }
267
+ }
268
+ const skipped = [];
269
+ for (const fileId of unknownRemovals.sort(compareCodepoints)) {
270
+ skipped.push(buildSkipLedgerEntry({
271
+ stage: "file_graph",
272
+ subjectKind: "file",
273
+ subjectId: fileId,
274
+ reason: "missing_index_entry",
275
+ detail: `a removal was reported for file id "${fileId}", but this graph never contained it; nothing was removed`,
276
+ recoverable: true,
277
+ }));
278
+ }
279
+ for (const fileId of [...toRecompute].sort(compareCodepoints)) {
280
+ const file = this.filesById.get(fileId);
281
+ if (file === undefined)
282
+ continue;
283
+ skipped.push(...this.rebuildEdgesOf(file));
284
+ }
285
+ this.refresh();
286
+ const currentEdgeIds = new Set(this.edgesById.keys());
287
+ const addedEdgeIds = [...currentEdgeIds].filter((id) => !previousEdgeIds.has(id));
288
+ const removedEdgeIds = [...previousEdgeIds].filter((id) => !currentEdgeIds.has(id));
289
+ const affectedFileIds = [];
290
+ for (const [id, sources] of this.adjacency.reverse) {
291
+ if (dependentsBefore.get(id) !== sources.join("/")) {
292
+ affectedFileIds.push(id);
293
+ }
294
+ }
295
+ for (const id of dependentsBefore.keys()) {
296
+ if (!this.adjacency.reverse.has(id)) {
297
+ affectedFileIds.push(id);
298
+ }
299
+ }
300
+ return {
301
+ recomputedFileIds: [...toRecompute].sort(compareCodepoints),
302
+ addedEdgeIds: addedEdgeIds.sort(compareCodepoints),
303
+ removedEdgeIds: removedEdgeIds.sort(compareCodepoints),
304
+ affectedFileIds: uniqueSortedByCodepoints(affectedFileIds),
305
+ skipped,
306
+ };
307
+ }
308
+ // -------------------------------------------------------------------------
309
+ // intern
310
+ // -------------------------------------------------------------------------
311
+ edgeIdBetween(from, to, direction) {
312
+ const source = direction === "forward" ? from : to;
313
+ const target = direction === "forward" ? to : from;
314
+ for (const edgeId of this.edgeIdsByFrom.get(source) ?? []) {
315
+ const edge = this.edgesById.get(edgeId);
316
+ if (edge?.resolution.status === "resolved" && edge.resolution.targetFileId === target) {
317
+ return edgeId;
318
+ }
319
+ }
320
+ return null;
321
+ }
322
+ /** Dateien, deren Aufloesung sich durch das Auftauchen/Verschwinden von `path` aendern kann. */
323
+ filesDependingOnPath(repoId, path) {
324
+ const stem = stemOf(path);
325
+ const result = new Set();
326
+ for (const edge of this.edgesById.values()) {
327
+ if (edge.resolution.status === "unresolved") {
328
+ if ((edge.resolution.rejectedCandidates ?? []).includes(path)) {
329
+ result.add(edge.fromFileId);
330
+ }
331
+ continue;
332
+ }
333
+ if (edge.resolution.status !== "resolved")
334
+ continue;
335
+ if (edge.resolution.targetRepoId !== repoId)
336
+ continue;
337
+ if (edge.resolution.targetPath === path || stemOf(edge.resolution.targetPath) === stem) {
338
+ result.add(edge.fromFileId);
339
+ }
340
+ }
341
+ return [...result].sort(compareCodepoints);
342
+ }
343
+ dropFile(fileId) {
344
+ this.removeEdgesOf(fileId);
345
+ this.filesById.delete(fileId);
346
+ this.nodesById.delete(fileId);
347
+ // Ohne diese Zeile blieben Ledger-Eintraege ueber eine Datei stehen, die
348
+ // der Graph nicht mehr kennt — Ueberberichten statt Verschweigen, aber
349
+ // `countsByReason` waere trotzdem falsch.
350
+ this.skipEntriesByFile.delete(fileId);
351
+ this.index.remove(fileId);
352
+ }
353
+ removeEdgesOf(fileId) {
354
+ for (const edgeId of this.edgeIdsByFrom.get(fileId) ?? []) {
355
+ this.edgesById.delete(edgeId);
356
+ }
357
+ this.edgeIdsByFrom.delete(fileId);
358
+ }
359
+ rebuildEdgesOf(file) {
360
+ this.removeEdgesOf(file.fileId);
361
+ const built = buildEdgesForFile(file, this.edgeContext);
362
+ const edgeIds = [];
363
+ for (const edge of built.edges) {
364
+ this.edgesById.set(edge.edgeId, edge);
365
+ edgeIds.push(edge.edgeId);
366
+ }
367
+ this.edgeIdsByFrom.set(file.fileId, edgeIds);
368
+ // Die Eintraege der vorigen Fassung dieser Datei werden ERSETZT, nicht
369
+ // ergaenzt — sonst waechst das Ledger bei jeder Fortschreibung um
370
+ // Duplikate. Ersetzt wird ueber die `file_id`, damit auch ein Pfadwechsel
371
+ // die alten Eintraege mitnimmt.
372
+ if (built.skipped.length === 0) {
373
+ this.skipEntriesByFile.delete(file.fileId);
374
+ }
375
+ else {
376
+ this.skipEntriesByFile.set(file.fileId, [...built.skipped]);
377
+ }
378
+ return built.skipped;
379
+ }
380
+ /** Baut Knoten, Nachbarschaft und Metrikzwischenspeicher neu auf. */
381
+ refresh() {
382
+ const nodeIds = [...this.filesById.keys()].sort(compareCodepoints);
383
+ this.adjacency = buildAdjacency(nodeIds, [...this.edgesById.values()]);
384
+ this.nodesById.clear();
385
+ for (const fileId of nodeIds) {
386
+ const file = this.filesById.get(fileId);
387
+ const edges = this.edgesFrom(fileId);
388
+ const node = {
389
+ schemaVersion: 1,
390
+ workspaceId: this.workspaceId,
391
+ repoId: file.repoId,
392
+ refId: file.refId,
393
+ fileId,
394
+ filePath: normalizePath(file.path),
395
+ language: file.languageId,
396
+ contentHash: file.contentHash,
397
+ imports: uniqueSortedByCodepoints(edges.map((edge) => edge.rawSpecifier)),
398
+ dependencies: [...(this.adjacency.forward.get(fileId) ?? [])],
399
+ dependents: [...(this.adjacency.reverse.get(fileId) ?? [])],
400
+ graphGeneration: this.graphGeneration,
401
+ unresolvedImportCount: edges.filter((edge) => edge.resolution.status === "unresolved")
402
+ .length,
403
+ };
404
+ // Paket- und Dienstzuordnung direkt bestimmen, NICHT aus einer Kante
405
+ // ableiten: eine Datei ohne Importe hat keine Kante, gehoert aber
406
+ // trotzdem zu einem Paket.
407
+ const owningPackage = assignPackage(this.topology.packages, file.repoId, file.path);
408
+ const owningService = assignContainerService(this.topology.services, file.repoId, file.path);
409
+ if (owningPackage !== null)
410
+ node.packageName = owningPackage.name;
411
+ if (owningService !== null)
412
+ node.containerService = owningService.name;
413
+ this.nodesById.set(fileId, node);
414
+ }
415
+ this.cachedMetrics = null;
416
+ }
417
+ }
418
+ /** Kurzform des Aufbaus. */
419
+ export function buildFileGraph(input) {
420
+ return FileDependencyGraph.build(input);
421
+ }
422
+ /**
423
+ * Stamm eines Pfades: ohne Erweiterung und ohne abschliessendes `index`.
424
+ * `src/util.ts`, `src/util.js` und `src/util/index.ts` haben denselben Stamm —
425
+ * genau die Dateien, die einander bei der Kandidatenprobe verdecken koennen.
426
+ */
427
+ export function stemOf(path) {
428
+ const normalized = normalizePath(path);
429
+ const extension = extensionOf(normalized);
430
+ const withoutExtension = extension === "" ? normalized : normalized.slice(0, normalized.length - extension.length);
431
+ return basenameOf(withoutExtension) === "index" ? dirnameOf(withoutExtension) : withoutExtension;
432
+ }
433
+ /**
434
+ * Kanonische Reihenfolge der Ledger-Eintraege.
435
+ *
436
+ * Ohne sie haengt die Reihenfolge daran, in welcher Folge Dateien verarbeitet
437
+ * wurden — und die haengt beim echten Scanner an der Nebenlaeufigkeit. Zwei
438
+ * Laeufe desselben Standes muessen dasselbe Dokument ergeben, sonst ist jeder
439
+ * daraus abgeleitete Hash wertlos.
440
+ */
441
+ function sortSkipEntries(entries) {
442
+ return [...entries].sort((left, right) => compareCodepoints(left.stage, right.stage) ||
443
+ compareCodepoints(left.subjectKind, right.subjectKind) ||
444
+ compareCodepoints(left.path ?? "", right.path ?? "") ||
445
+ compareCodepoints(left.reason, right.reason) ||
446
+ compareCodepoints(left.detail, right.detail));
447
+ }
448
+ //# sourceMappingURL=graph.js.map
@@ -0,0 +1 @@
1
+ {"version":3,"file":"graph.js","sourceRoot":"","sources":["../src/graph.ts"],"names":[],"mappings":"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"}
@@ -0,0 +1,35 @@
1
+ /**
2
+ * `@untangle-code/file-graph` — der Dateiabhaengigkeitsgraph (spec.md §14,
3
+ * architecture.md §16).
4
+ *
5
+ * Beantwortet drei Fragen:
6
+ * - Welche Datei haengt von welcher ab (`dependenciesOf`)?
7
+ * - Wer bricht, wenn ich diese Datei aendere (`dependentsOf`)?
8
+ * - Wie haengen die Teilprojekte eines Monorepos zusammen
9
+ * (`loadWorkspaceTopology`: Pakete UND Container-Dienste)?
10
+ *
11
+ * Dieses Modul ist der EINZIGE oeffentliche Export des Pakets.
12
+ */
13
+ export * from "./paths.js";
14
+ export * from "./types.js";
15
+ export * from "./file-index.js";
16
+ export * from "./assignment.js";
17
+ export * from "./topology/jsonc.js";
18
+ export * from "./topology/manifest.js";
19
+ export * from "./topology/project-config.js";
20
+ export * from "./topology/workspace-definition.js";
21
+ export * from "./topology/compose.js";
22
+ export * from "./topology/load.js";
23
+ export * from "./resolve/candidates.js";
24
+ export * from "./resolve/package-exports.js";
25
+ export * from "./resolve/resolvers.js";
26
+ export * from "./resolve/pipeline.js";
27
+ export * from "./edges.js";
28
+ export * from "./metrics.js";
29
+ export * from "./graph.js";
30
+ export { traverseFileGraph } from "./traverse.js";
31
+ export type { FileGraphNeighborhoodV1, TraverseFileGraphOptionsV1 } from "./traverse.js";
32
+ export * from "./persistence.js";
33
+ export * from "./restore.js";
34
+ export * from "./boundaries/index.js";
35
+ //# sourceMappingURL=index.d.ts.map
@@ -0,0 +1 @@
1
+ {"version":3,"file":"index.d.ts","sourceRoot":"","sources":["../src/index.ts"],"names":[],"mappings":"AAAA;;;;;;;;;;;GAWG;AAGH,cAAc,YAAY,CAAC;AAG3B,cAAc,YAAY,CAAC;AAG3B,cAAc,iBAAiB,CAAC;AAGhC,cAAc,iBAAiB,CAAC;AAGhC,cAAc,qBAAqB,CAAC;AACpC,cAAc,wBAAwB,CAAC;AACvC,cAAc,8BAA8B,CAAC;AAC7C,cAAc,oCAAoC,CAAC;AACnD,cAAc,uBAAuB,CAAC;AACtC,cAAc,oBAAoB,CAAC;AAGnC,cAAc,yBAAyB,CAAC;AACxC,cAAc,8BAA8B,CAAC;AAC7C,cAAc,wBAAwB,CAAC;AACvC,cAAc,uBAAuB,CAAC;AAGtC,cAAc,YAAY,CAAC;AAC3B,cAAc,cAAc,CAAC;AAC7B,cAAc,YAAY,CAAC;AAO3B,OAAO,EAAE,iBAAiB,EAAE,MAAM,eAAe,CAAC;AAClD,YAAY,EAAE,uBAAuB,EAAE,0BAA0B,EAAE,MAAM,eAAe,CAAC;AAGzF,cAAc,kBAAkB,CAAC;AAGjC,cAAc,cAAc,CAAC;AAC7B,cAAc,uBAAuB,CAAC"}
package/dist/index.js ADDED
@@ -0,0 +1,48 @@
1
+ /**
2
+ * `@untangle-code/file-graph` — der Dateiabhaengigkeitsgraph (spec.md §14,
3
+ * architecture.md §16).
4
+ *
5
+ * Beantwortet drei Fragen:
6
+ * - Welche Datei haengt von welcher ab (`dependenciesOf`)?
7
+ * - Wer bricht, wenn ich diese Datei aendere (`dependentsOf`)?
8
+ * - Wie haengen die Teilprojekte eines Monorepos zusammen
9
+ * (`loadWorkspaceTopology`: Pakete UND Container-Dienste)?
10
+ *
11
+ * Dieses Modul ist der EINZIGE oeffentliche Export des Pakets.
12
+ */
13
+ // Pfadhilfen (POSIX, repo-relativ)
14
+ export * from "./paths.js";
15
+ // Vertraege des Pakets
16
+ export * from "./types.js";
17
+ // Dateiverzeichnis der Aufloesung
18
+ export * from "./file-index.js";
19
+ // Zuordnung Datei → Paket / Container-Dienst
20
+ export * from "./assignment.js";
21
+ // Topologie: Manifeste, Projektkonfigurationen, Workspace-Definition, Compose
22
+ export * from "./topology/jsonc.js";
23
+ export * from "./topology/manifest.js";
24
+ export * from "./topology/project-config.js";
25
+ export * from "./topology/workspace-definition.js";
26
+ export * from "./topology/compose.js";
27
+ export * from "./topology/load.js";
28
+ // Modulaufloesung
29
+ export * from "./resolve/candidates.js";
30
+ export * from "./resolve/package-exports.js";
31
+ export * from "./resolve/resolvers.js";
32
+ export * from "./resolve/pipeline.js";
33
+ // Kanten, Metriken, Graph
34
+ export * from "./edges.js";
35
+ export * from "./metrics.js";
36
+ export * from "./graph.js";
37
+ // Die Traversierung als freie Funktion — sie bedient den gebauten UND den
38
+ // zurueckgeladenen Graphen. `DEFAULT_TRAVERSAL_LIMITS` und `MonotonicClock`
39
+ // stehen bewusst NICHT hier, sondern kommen weiter aus `graph.js`: sie waren
40
+ // immer schon dort zu haben, und zwei Sternexporte desselben Namens waeren
41
+ // ein doppelter Ausgang fuer eine einzige Sache.
42
+ export { traverseFileGraph } from "./traverse.js";
43
+ // Ablage ueber den bestehenden GraphStore-Port
44
+ export * from "./persistence.js";
45
+ // Lesepfad: aus einem Abbild wieder einen abfragbaren Graphen machen
46
+ export * from "./restore.js";
47
+ export * from "./boundaries/index.js";
48
+ //# sourceMappingURL=index.js.map
@@ -0,0 +1 @@
1
+ {"version":3,"file":"index.js","sourceRoot":"","sources":["../src/index.ts"],"names":[],"mappings":"AAAA;;;;;;;;;;;GAWG;AAEH,mCAAmC;AACnC,cAAc,YAAY,CAAC;AAE3B,uBAAuB;AACvB,cAAc,YAAY,CAAC;AAE3B,kCAAkC;AAClC,cAAc,iBAAiB,CAAC;AAEhC,6CAA6C;AAC7C,cAAc,iBAAiB,CAAC;AAEhC,8EAA8E;AAC9E,cAAc,qBAAqB,CAAC;AACpC,cAAc,wBAAwB,CAAC;AACvC,cAAc,8BAA8B,CAAC;AAC7C,cAAc,oCAAoC,CAAC;AACnD,cAAc,uBAAuB,CAAC;AACtC,cAAc,oBAAoB,CAAC;AAEnC,kBAAkB;AAClB,cAAc,yBAAyB,CAAC;AACxC,cAAc,8BAA8B,CAAC;AAC7C,cAAc,wBAAwB,CAAC;AACvC,cAAc,uBAAuB,CAAC;AAEtC,0BAA0B;AAC1B,cAAc,YAAY,CAAC;AAC3B,cAAc,cAAc,CAAC;AAC7B,cAAc,YAAY,CAAC;AAE3B,0EAA0E;AAC1E,4EAA4E;AAC5E,6EAA6E;AAC7E,2EAA2E;AAC3E,iDAAiD;AACjD,OAAO,EAAE,iBAAiB,EAAE,MAAM,eAAe,CAAC;AAGlD,+CAA+C;AAC/C,cAAc,kBAAkB,CAAC;AAEjC,qEAAqE;AACrE,cAAc,cAAc,CAAC;AAC7B,cAAc,uBAAuB,CAAC"}
@@ -0,0 +1,67 @@
1
+ /**
2
+ * Graphmetriken des Dateigraphen (spec.md §14.4).
3
+ *
4
+ * Alle Verfahren sind ITERATIV implementiert, nicht rekursiv. Ein Monorepo
5
+ * mit zehntausenden Dateien hat Ketten, die jeden Aufrufstapel sprengen; ein
6
+ * `RangeError` mitten in der Statistik waere ein Totalausfall der Kennzahlen.
7
+ *
8
+ * ZYKLEN: Die Aufzaehlung elementarer Zyklen ist im schlechtesten Fall
9
+ * exponentiell. Sie laeuft deshalb gegen ein Budget — und wenn das Budget
10
+ * greift, steht das in `truncationReason`. Eine abgeschnittene Zyklusliste
11
+ * darf nie wie eine vollstaendige aussehen (E4).
12
+ */
13
+ import type { FileEdgeV1, FileGraphMetricsV1, FileNodeV1 } from "@untangle-code/domain";
14
+ import type { FileGraphLimitsV1 } from "./types.js";
15
+ /** Benannte Formel hinter `FileGraphCentralityEntryV1.centrality`. */
16
+ export declare const CENTRALITY_FORMULA = "degree-centrality-v1: (inDegree + outDegree) / (2 * max(1, nodeCount - 1)), clamped to [0, 1]";
17
+ export declare const DEFAULT_GRAPH_LIMITS: FileGraphLimitsV1;
18
+ /** Gerichtete Nachbarschaftslisten, aus aufgeloesten Kanten gebaut. */
19
+ export interface AdjacencyV1 {
20
+ /** fileId → Ziel-fileIds, codepoint-sortiert und dedupliziert. */
21
+ forward: Map<string, string[]>;
22
+ /** fileId → Quell-fileIds, codepoint-sortiert und dedupliziert. */
23
+ reverse: Map<string, string[]>;
24
+ }
25
+ /**
26
+ * Baut die Nachbarschaft aus den Kanten.
27
+ *
28
+ * Nur `resolved`-Kanten mit einem Ziel INNERHALB der Knotenmenge zaehlen —
29
+ * eine externe Abhaengigkeit hat keinen Knoten, und eine unaufgeloeste erst
30
+ * recht nicht. Beide bleiben als Kante erhalten und in der
31
+ * Import-Resolution-Rate sichtbar, sie sind nur keine Graphverbindung.
32
+ */
33
+ export declare function buildAdjacency(nodeIds: readonly string[], edges: readonly FileEdgeV1[]): AdjacencyV1;
34
+ /**
35
+ * Stark zusammenhaengende Komponenten nach Tarjan, iterativ.
36
+ *
37
+ * Ergebnis enthaelt NUR Komponenten mit mehr als einem Knoten — eine
38
+ * einelementige Komponente ohne Selbstschleife ist kein Befund. Selbstbezuege
39
+ * kommen ueber `findCycles` als einelementige Zyklen zurueck.
40
+ */
41
+ export declare function stronglyConnectedComponents(nodeIds: readonly string[], forward: ReadonlyMap<string, readonly string[]>): string[][];
42
+ /** Ergebnis der Zyklensuche. */
43
+ export interface CycleSearchResultV1 {
44
+ /** Jeder Zyklus als geordnete Liste seiner file_ids, ohne Wiederholung des Startknotens. */
45
+ cycles: string[][];
46
+ /** Gesetzt, wenn ein Budget die Suche beendet hat. */
47
+ truncationReason?: string;
48
+ }
49
+ /**
50
+ * Zaehlt elementare Zyklen auf, komponentenweise und gegen ein Budget.
51
+ *
52
+ * Vorgehen: je stark zusammenhaengender Komponente wird von jedem Knoten aus
53
+ * gesucht, aber nur ueber Knoten, die in der komponenteninternen Ordnung NICHT
54
+ * VOR dem Startknoten liegen. Damit wird jeder Zyklus genau einmal gefunden
55
+ * (an seinem kleinsten Knoten) statt einmal je Rotation.
56
+ */
57
+ export declare function findCycles(nodeIds: readonly string[], forward: ReadonlyMap<string, readonly string[]>, components: readonly (readonly string[])[], limits: FileGraphLimitsV1): CycleSearchResultV1;
58
+ /** Berechnet die vollstaendige Metrikaufstellung. */
59
+ export declare function computeFileGraphMetrics(input: {
60
+ workspaceId: string;
61
+ graphGeneration: string;
62
+ nodes: readonly FileNodeV1[];
63
+ edges: readonly FileEdgeV1[];
64
+ adjacency: AdjacencyV1;
65
+ limits: FileGraphLimitsV1;
66
+ }): FileGraphMetricsV1;
67
+ //# sourceMappingURL=metrics.d.ts.map
@@ -0,0 +1 @@
1
+ {"version":3,"file":"metrics.d.ts","sourceRoot":"","sources":["../src/metrics.ts"],"names":[],"mappings":"AAAA;;;;;;;;;;;GAWG;AACH,OAAO,KAAK,EACV,UAAU,EAEV,kBAAkB,EAClB,UAAU,EACX,MAAM,uBAAuB,CAAC;AAG/B,OAAO,KAAK,EAAE,iBAAiB,EAAE,MAAM,YAAY,CAAC;AAEpD,sEAAsE;AACtE,eAAO,MAAM,kBAAkB,kGACkE,CAAC;AAElG,eAAO,MAAM,oBAAoB,EAAE,iBAIlC,CAAC;AAEF,uEAAuE;AACvE,MAAM,WAAW,WAAW;IAC1B,kEAAkE;IAClE,OAAO,EAAE,GAAG,CAAC,MAAM,EAAE,MAAM,EAAE,CAAC,CAAC;IAC/B,mEAAmE;IACnE,OAAO,EAAE,GAAG,CAAC,MAAM,EAAE,MAAM,EAAE,CAAC,CAAC;CAChC;AAED;;;;;;;GAOG;AACH,wBAAgB,cAAc,CAC5B,OAAO,EAAE,SAAS,MAAM,EAAE,EAC1B,KAAK,EAAE,SAAS,UAAU,EAAE,GAC3B,WAAW,CAsBb;AAED;;;;;;GAMG;AACH,wBAAgB,2BAA2B,CACzC,OAAO,EAAE,SAAS,MAAM,EAAE,EAC1B,OAAO,EAAE,WAAW,CAAC,MAAM,EAAE,SAAS,MAAM,EAAE,CAAC,GAC9C,MAAM,EAAE,EAAE,CA+DZ;AAED,gCAAgC;AAChC,MAAM,WAAW,mBAAmB;IAClC,4FAA4F;IAC5F,MAAM,EAAE,MAAM,EAAE,EAAE,CAAC;IACnB,sDAAsD;IACtD,gBAAgB,CAAC,EAAE,MAAM,CAAC;CAC3B;AAED;;;;;;;GAOG;AACH,wBAAgB,UAAU,CACxB,OAAO,EAAE,SAAS,MAAM,EAAE,EAC1B,OAAO,EAAE,WAAW,CAAC,MAAM,EAAE,SAAS,MAAM,EAAE,CAAC,EAC/C,UAAU,EAAE,SAAS,CAAC,SAAS,MAAM,EAAE,CAAC,EAAE,EAC1C,MAAM,EAAE,iBAAiB,GACxB,mBAAmB,CAsErB;AAED,qDAAqD;AACrD,wBAAgB,uBAAuB,CAAC,KAAK,EAAE;IAC7C,WAAW,EAAE,MAAM,CAAC;IACpB,eAAe,EAAE,MAAM,CAAC;IACxB,KAAK,EAAE,SAAS,UAAU,EAAE,CAAC;IAC7B,KAAK,EAAE,SAAS,UAAU,EAAE,CAAC;IAC7B,SAAS,EAAE,WAAW,CAAC;IACvB,MAAM,EAAE,iBAAiB,CAAC;CAC3B,GAAG,kBAAkB,CAqFrB"}