Skip to content

Commit 2f61aa7

Browse files
fix(context): normalize Rsdoctor module relations
1 parent b3e92b6 commit 2f61aa7

2 files changed

Lines changed: 67 additions & 8 deletions

File tree

packages/context/src/rsdoctorGraph.ts

Lines changed: 23 additions & 8 deletions
Original file line numberDiff line numberDiff line change
@@ -150,20 +150,35 @@ const normalizeRsdoctorModuleGraph = (artifact: RsdoctorArtifact): ObservedModul
150150

151151
const edgeKeys = new Set<string>();
152152
const edges: ObservedModuleGraph['edges'] = [];
153-
for (const row of Array.isArray(moduleGraph.dependencies) ? moduleGraph.dependencies : []) {
154-
if (!isObject(row)) continue;
155-
const usesDependencyShape = Object.hasOwn(row, 'dependency');
156-
const from = getId(usesDependencyShape ? row.module : row.issuer);
157-
const to = getId(usesDependencyShape ? row.dependency : row.module);
158-
if (from === undefined || to === undefined) continue;
153+
const addEdge = (from: string | undefined, to: string | undefined): void => {
154+
if (from === undefined || to === undefined) return;
159155
if (!modulesById.has(from) || !modulesById.has(to)) {
160156
if (!issues.includes('dangling-edge')) issues.push('dangling-edge');
161-
continue;
157+
return;
162158
}
163159
const key = `${from}\u0000${to}`;
164-
if (edgeKeys.has(key)) continue;
160+
if (edgeKeys.has(key)) return;
165161
edgeKeys.add(key);
166162
edges.push({ from, to });
163+
};
164+
for (const row of Array.isArray(moduleGraph.dependencies) ? moduleGraph.dependencies : []) {
165+
if (!isObject(row)) continue;
166+
const usesDependencyShape = Object.hasOwn(row, 'dependency');
167+
addEdge(
168+
getId(usesDependencyShape ? row.module : row.issuer),
169+
getId(usesDependencyShape ? row.dependency : row.module),
170+
);
171+
}
172+
173+
for (const row of Array.isArray(moduleGraph.modules) ? moduleGraph.modules : []) {
174+
if (!isObject(row)) continue;
175+
const moduleId = getId(row.id);
176+
for (const importerId of Array.isArray(row.imported) ? row.imported.map(getId) : []) {
177+
addEdge(importerId, moduleId);
178+
}
179+
for (const childId of Array.isArray(row.modules) ? row.modules.map(getId) : []) {
180+
addEdge(moduleId, childId);
181+
}
167182
}
168183

169184
return {

packages/context/tests/rsdoctorGraph.test.ts

Lines changed: 44 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -194,6 +194,50 @@ test('inherits chunk membership from a concatenated module container', async ()
194194
}
195195
});
196196

197+
test('connects module importers and concatenated children for reachability', async () => {
198+
const workspaceRoot = await mkdtemp(path.join(os.tmpdir(), 'rstack-rsdoctor-graph-'));
199+
try {
200+
await writeFile(
201+
path.join(workspaceRoot, 'rsdoctor-data.json'),
202+
JSON.stringify({
203+
data: {
204+
moduleGraph: {
205+
modules: [
206+
{
207+
id: 1,
208+
path: '/workspace/src/index.ts',
209+
isEntry: true,
210+
imported: [],
211+
modules: [2],
212+
},
213+
{
214+
id: 2,
215+
path: '/workspace/src/feature.ts',
216+
imported: [3],
217+
},
218+
{
219+
id: 3,
220+
path: '/workspace/src/consumer.ts',
221+
imported: [],
222+
},
223+
],
224+
dependencies: [],
225+
},
226+
},
227+
}),
228+
);
229+
230+
const graph = await readRsdoctorModuleGraph(workspaceRoot, 'rsdoctor-data.json');
231+
232+
expect(graph.edges).toEqual([
233+
{ from: '1', to: '2' },
234+
{ from: '3', to: '2' },
235+
]);
236+
} finally {
237+
await rm(workspaceRoot, { force: true, recursive: true });
238+
}
239+
});
240+
197241
test('reports a missing module graph as insufficient ordinary artifact data', async () => {
198242
const workspaceRoot = await mkdtemp(path.join(os.tmpdir(), 'rstack-rsdoctor-graph-'));
199243
try {

0 commit comments

Comments
 (0)