Skip to content

Commit

Permalink
feat: re-structure the search API schema
Browse files Browse the repository at this point in the history
  • Loading branch information
wtlin1228 committed Oct 5, 2024
1 parent 070515f commit b17ab4f
Show file tree
Hide file tree
Showing 6 changed files with 98 additions and 47 deletions.
97 changes: 72 additions & 25 deletions crates/api_server/src/main.rs
Original file line number Diff line number Diff line change
Expand Up @@ -3,7 +3,7 @@ use actix_web::{error, get, web, App, HttpServer, Result};
use dt_core::{
graph::used_by_graph::UsedByGraph,
portable::Portable,
tracker::{DependencyTracker, ModuleSymbol, TraceTarget},
tracker::{DependencyTracker, TraceTarget},
};
use serde::Serialize;
use std::{
Expand All @@ -19,11 +19,16 @@ struct AppState {
used_by_graph: UsedByGraph,
}

#[derive(Serialize, Clone)]
struct Step {
module_path: String,
symbol_name: String,
}

#[derive(Serialize)]
struct SearchResponse {
project_root: String,
i18n_to_symbol: HashMap<String, HashSet<String>>,
trace_result: HashMap<String, HashMap<String, Vec<Vec<ModuleSymbol>>>>,
trace_result: HashMap<String, HashMap<String, HashMap<String, Vec<Vec<Step>>>>>,
}

#[get("/search/{search}")]
Expand All @@ -35,41 +40,83 @@ async fn search(

// TODO: deal with search mode

match data.i18n_to_symbol.get(&search) {
None => Err(error::ErrorNotFound(format!("{} not found", search))),
Some(ts) => {
let mut dependency_tracker = DependencyTracker::new(&data.used_by_graph, true);
let mut trace_result: HashMap<String, HashMap<String, Vec<Vec<ModuleSymbol>>>> =
HashMap::new();
for (module_path, symbols) in ts {
trace_result.insert(module_path.to_owned(), HashMap::new());
let mut dependency_tracker = DependencyTracker::new(&data.used_by_graph, true);
let matched_i18n_keys = vec![&search];
let mut trace_result = HashMap::new();
for i18n_key in matched_i18n_keys {
let mut route_to_paths = HashMap::new();
if let Some(i18n_key_usage) = data.i18n_to_symbol.get(i18n_key) {
for (module_path, symbols) in i18n_key_usage {
for symbol in symbols {
let full_paths = dependency_tracker
.trace((module_path.clone(), TraceTarget::LocalVar(symbol.clone())))
.unwrap();
trace_result
.entry(module_path.to_owned())
.and_modify(|symbol_table| {
symbol_table.insert(symbol.to_owned(), full_paths);
});
// traverse each path and check if any symbol is used in some routes
for mut full_path in full_paths {
full_path.reverse();
for (i, (step_module_path, step_trace_target)) in
full_path.iter().enumerate()
{
match step_trace_target {
TraceTarget::LocalVar(step_symbol_name) => {
if let Some(symbol_to_routes) =
data.symbol_to_route.get(step_module_path)
{
if let Some(routes) = symbol_to_routes.get(step_symbol_name)
{
let dependency_from_target_to_route: Vec<Step> =
full_path[0..i]
.iter()
.map(|(path, target)| Step {
module_path: path.clone(),
symbol_name: target.to_string(),
})
.collect();
for route in routes.iter() {
if !route_to_paths.contains_key(route) {
route_to_paths
.insert(route.clone(), HashMap::new());
}
if !route_to_paths
.get(route)
.unwrap()
.contains_key(symbol)
{
route_to_paths
.get_mut(route)
.unwrap()
.insert(symbol.to_string(), vec![]);
}
route_to_paths
.get_mut(route)
.unwrap()
.get_mut(symbol)
.unwrap()
.push(dependency_from_target_to_route.clone());
}
}
}
}
_ => (),
}
}
}
}
}

Ok(web::Json(SearchResponse {
project_root: data.project_root.to_owned(),
i18n_to_symbol: ts.to_owned(),
trace_result,
}))
}
trace_result.insert(i18n_key.to_string(), route_to_paths);
}

Ok(web::Json(SearchResponse {
project_root: data.project_root.to_owned(),
trace_result,
}))
}

#[actix_web::main]
async fn main() -> std::io::Result<()> {
// TODO: get portable path from args
// let mut file = File::open("<the portable path>")?;
let mut file =
File::open("/Users/linweitang/rust/js-symbol-dependency-tracker/outputs/sample.json")?;
let mut file = File::open("<the portable path>")?;
let mut exported = String::new();
file.read_to_string(&mut exported)?;
let portable = Portable::import(&exported).unwrap();
Expand Down
34 changes: 17 additions & 17 deletions web/src/search/api-mock.ts
Original file line number Diff line number Diff line change
Expand Up @@ -2,9 +2,9 @@ import { SearchResult } from "./api";

const mockedTraceResult = {
"i18n.key.pikachu": {
"/account": [
"/account": {
// paths from Avatar to /account
[
Avatar: [
// path 1
[
{
Expand Down Expand Up @@ -56,14 +56,18 @@ const mockedTraceResult = {
},
],
],
],
},
},
"i18n.key.pikapi": {
"/home": [
"/home": {
// paths from Header to /home
[
Header: [
// path 1
[
{
module_path: "module/path/can/be/super/long/too/bad/Header.tsx",
symbol_name: "Header",
},
{
module_path: "module/path/can/be/super/long/too/bad/Layout.tsx",
symbol_name: "Layout",
Expand All @@ -72,18 +76,18 @@ const mockedTraceResult = {
module_path: "module/path/can/be/super/long/too/bad/Home.tsx",
symbol_name: "Home",
},
{
module_path: "module/path/can/be/super/long/too/bad/Header.tsx",
symbol_name: "Header",
},
],
],
],
"/account": [
},
"/account": {
// paths from Header to /account
[
Header: [
// path 1
[
{
module_path: "module/path/can/be/super/long/too/bad/Header.tsx",
symbol_name: "Header",
},
{
module_path:
"module/path/can/be/super/long/too/bad/UserProfileHeader.tsx",
Expand All @@ -98,13 +102,9 @@ const mockedTraceResult = {
module_path: "module/path/can/be/super/long/too/bad/Account.tsx",
symbol_name: "Account",
},
{
module_path: "module/path/can/be/super/long/too/bad/Header.tsx",
symbol_name: "Header",
},
],
],
],
},
},
};

Expand Down
6 changes: 3 additions & 3 deletions web/src/search/components/TreeView.tsx
Original file line number Diff line number Diff line change
Expand Up @@ -99,12 +99,12 @@ export const TreeView = React.memo(function TreeView({
itemId={`${i18nKey} - ${url}`}
label={url}
>
{traceTargets.map((traceTarget, i) => (
{Object.entries(traceTargets).map(([traceTarget, paths]) => (
<TracePathToTreeView
key={`${i18nKey} - ${url} - path${i}`}
key={`${i18nKey} - ${url} - ${traceTarget}`}
tracePaths={mapAllModuleSymbolToString(
data.project_root,
traceTarget
paths
)}
/>
))}
Expand Down
6 changes: 4 additions & 2 deletions web/src/search/shared/type.ts
Original file line number Diff line number Diff line change
Expand Up @@ -6,9 +6,11 @@ export type ModuleSymbol = {
symbol_name: string;
};
export type TracePath = ModuleSymbol[];
export type TraceTarget = TracePath[];

// Trace result might have multiple i18n keys, each i18n key might be
// used in multiple module symbols, and each module symbol might be
// used in multiple urls through different paths.
export type TraceResult = Record<I18nKey, Record<Url, TraceTarget[]>>;
export type TraceResult = Record<
I18nKey,
Record<Url, Record<string, TracePath[]>>
>;
1 change: 1 addition & 0 deletions web/tsconfig.app.tsbuildinfo
Original file line number Diff line number Diff line change
@@ -0,0 +1 @@
{"root":["./src/app.tsx","./src/main.tsx","./src/vite-env.d.ts","./src/search/api-mock.ts","./src/search/api.ts","./src/search/index.tsx","./src/search/components/searchinput.tsx","./src/search/components/treeview.tsx","./src/search/shared/type.ts"],"version":"5.6.2"}
1 change: 1 addition & 0 deletions web/tsconfig.node.tsbuildinfo
Original file line number Diff line number Diff line change
@@ -0,0 +1 @@
{"root":["./vite.config.ts"],"version":"5.6.2"}

0 comments on commit b17ab4f

Please sign in to comment.