MCPcopy Create free account
hub / github.com/colbymchenry/codegraph / tanstackLinkEdges

Function tanstackLinkEdges

src/resolution/tanstack-router-synthesizer.ts:49–108  ·  view source on GitHub ↗
(ctx: ResolutionContext, onYield: MaybeYield)

Source from the content-addressed store, hash-verified

47const MAX_LINKS_PER_COMPONENT = 24;
48
49export async function tanstackLinkEdges(ctx: ResolutionContext, onYield: MaybeYield): Promise<Edge[]> {
50 const table = tanstackTable(ctx);
51 if (table.byRoot.size === 0) return [];
52 const edges: Edge[] = [];
53 const seen = new Set<string>();
54 const perComponent = new Map<string, number>();
55 let scanned = 0;
56 for (const file of ctx.getAllFiles()) {
57 if (!JSX_FILE.test(file) || isTestPath(file)) continue;
58 const routes = routesForFile(table, file);
59 if (!routes || routes.exact.size === 0) continue;
60 if ((++scanned & 63) === 0) await onYield();
61 const source = ctx.readFile(file);
62 if (!source || !HAS_LINK_TAG.test(source)) continue;
63 const safe = stripCommentsForRegex(source, 'typescript');
64 const nodes = ctx.getNodesInFile(file);
65 const lineOf = makeLineAt(safe, 1);
66 LINK_TAG.lastIndex = 0;
67 let m: RegExpExecArray | null;
68 while ((m = LINK_TAG.exec(safe)) !== null) {
69 let literal: string | null = m[3] ?? m[4] ?? null;
70 if (literal === null) {
71 // `to={…}`: a string or a template.
72 const at = m.index + m[0].length;
73 const ch = safe[at];
74 if (ch === '"' || ch === "'" || ch === '`') literal = readStringAt(safe, at);
75 }
76 if (literal === null) continue;
77 const href = tanstackDestination(JSON.stringify(literal));
78 if (!href) continue;
79 const line = lineOf(m.index);
80 const component = enclosingFn(nodes, line);
81 if (!component) continue;
82 // A destination written as a choice names one route per arm, and the
83 // user reaches every one of them — each is drawn.
84 for (const { node: route, href: arm } of destinationsForHref(href, routes)) {
85 const key = `${component.id}>${route.id}`;
86 if (seen.has(key)) continue;
87 const count = (perComponent.get(component.id) ?? 0) + 1;
88 perComponent.set(component.id, count);
89 if (count > MAX_LINKS_PER_COMPONENT) continue;
90 seen.add(key);
91 edges.push({
92 source: component.id,
93 target: route.id,
94 kind: 'navigates',
95 line,
96 provenance: 'heuristic',
97 metadata: {
98 synthesizedBy: 'tanstack-link',
99 href: arm.display,
100 navMethod: m[1] === 'Navigate' ? 'navigate' : 'link',
101 registeredAt: `${file}:${line}`,
102 },
103 });
104 }
105 }
106 }

Callers 1

Calls 15

tanstackTableFunction · 0.90
isTestPathFunction · 0.90
routesForFileFunction · 0.90
stripCommentsForRegexFunction · 0.90
makeLineAtFunction · 0.90
readStringAtFunction · 0.90
tanstackDestinationFunction · 0.90
enclosingFnFunction · 0.90
destinationsForHrefFunction · 0.90
readFileMethod · 0.80
hasMethod · 0.80
addMethod · 0.80

Tested by

no test coverage detected