(queryType: string, target: string, params: any)
| 520 | |
| 521 | // 5. Execute query callback from Supabase Realtime Tunnel |
| 522 | const executeQueryCallback = async (queryType: string, target: string, params: any) => { |
| 523 | console.log(`[Explore Tunnel] Running WASM query: type=${queryType}, target=${target}`); |
| 524 | |
| 525 | const targetRepo = params?.repo || ""; |
| 526 | const currentGraph = await resolveGraph(targetRepo); |
| 527 | |
| 528 | if (!currentGraph) { |
| 529 | throw new Error(`SILENT_IGNORE: The repository '${targetRepo}' is not actively loaded or cached in this browser tab.`); |
| 530 | } |
| 531 | |
| 532 | const cleanTarget = target?.trim(); |
| 533 | const nodes = currentGraph.nodes || []; |
| 534 | const links = currentGraph.links || []; |
| 535 | |
| 536 | switch (queryType) { |
| 537 | case "definitions": { |
| 538 | if (!cleanTarget) return { error: "Missing required argument 'target'." }; |
| 539 | const results = nodes.filter((n: any) => n.name === cleanTarget); |
| 540 | return { results }; |
| 541 | } |
| 542 | |
| 543 | case "callers": { |
| 544 | if (!cleanTarget) return { error: "Missing required argument 'target'." }; |
| 545 | const targetNode = nodes.find((n: any) => n.name === cleanTarget); |
| 546 | if (!targetNode) return { results: [] }; |
| 547 | const callerLinks = links.filter((l: any) => l.target === targetNode.id && l.type === "CALLS"); |
| 548 | const callerIds = new Set(callerLinks.map((l: any) => l.source)); |
| 549 | const results = nodes.filter((n: any) => callerIds.has(n.id)); |
| 550 | return { results }; |
| 551 | } |
| 552 | |
| 553 | case "callees": { |
| 554 | if (!cleanTarget) return { error: "Missing required argument 'target'." }; |
| 555 | const targetNode = nodes.find((n: any) => n.name === cleanTarget); |
| 556 | if (!targetNode) return { results: [] }; |
| 557 | const calleeLinks = links.filter((l: any) => l.source === targetNode.id && l.type === "CALLS"); |
| 558 | const calleeIds = new Set(calleeLinks.map((l: any) => l.target)); |
| 559 | const results = nodes.filter((n: any) => calleeIds.has(n.id)); |
| 560 | return { results }; |
| 561 | } |
| 562 | |
| 563 | case "file_structure": { |
| 564 | if (!cleanTarget) return { error: "Missing required argument 'target' (file path)." }; |
| 565 | const results = nodes.filter((n: any) => n.file === cleanTarget || n.path === cleanTarget); |
| 566 | return { results }; |
| 567 | } |
| 568 | |
| 569 | case "search": { |
| 570 | if (!cleanTarget) return { error: "Missing required argument 'target'." }; |
| 571 | const query = cleanTarget.toLowerCase(); |
| 572 | const results = nodes.filter((n: any) => n.name?.toLowerCase().includes(query) || n.file?.toLowerCase().includes(query)); |
| 573 | return { results: results.slice(0, 50) }; |
| 574 | } |
| 575 | |
| 576 | case "cypher": { |
| 577 | const cypherQuery = params?.cypher_query || target || ""; |
| 578 | console.log(`[Explore Tunnel] Running local Cypher emulation: ${cypherQuery}`); |
| 579 | return { |
nothing calls this directly
no test coverage detected