Skip to main content

DevelopmentNodeEnvironment_MicrosoftVSCodeDependency_22NodeVersion_Bundle_Clean_Debug_ElectronProfile_EsbuildCompiler_Mountain/IPC/WindServiceHandlers/TreeView/
GetChildren.rs

1//! Wire method: `tree:getChildren`.
2//! Renderer-side tree-view child lookup. Mirrors the Cocoon→Mountain
3//! `GetTreeChildren` gRPC path but is invoked directly by the Wind/Sky
4//! tree-view bridge so the UI can request children without waiting for
5//! Cocoon to ask first.
6//!
7//! Waits up to 5 s for the Cocoon gRPC connection (boot-race guard) then
8//! dispatches `$provideTreeChildren` with a 5 s timeout. On timeout or
9//! extension rejection the workbench receives `{ items: [] }` and schedules
10//! its own retry when the view scrolls back into view.
11
12use std::sync::Arc;
13
14use serde_json::{Value, json};
15use tauri::AppHandle;
16
17use crate::RunTime::ApplicationRunTime::ApplicationRunTime;
18
19pub async fn Fn(
20	ApplicationHandle:AppHandle,
21
22	RunTime:Arc<ApplicationRunTime>,
23
24	Arguments:Vec<Value>,
25) -> Result<Value, String> {
26	let ViewId = Arguments
27		.first()
28		.and_then(|V| V.get("viewId").or_else(|| V.get(0)))
29		.and_then(Value::as_str)
30		.unwrap_or("")
31		.to_string();
32
33	let ItemHandle = Arguments
34		.first()
35		.and_then(|V| V.get("treeItemHandle").or_else(|| V.get(1)))
36		.and_then(Value::as_str)
37		.unwrap_or("")
38		.to_string();
39
40	crate::dev_log!(
41		"tree-view",
42		"[TreeView] invoke:getChildren view={} parent={}",
43		ViewId,
44		ItemHandle
45	);
46
47	if ViewId.is_empty() {
48		return Err("tree:getChildren requires viewId".to_string());
49	}
50
51	let Parameters = json!({
52		"viewId": ViewId,
53		"treeItemHandle": ItemHandle,
54	});
55
56	// Boot-race: the workbench's Explorer view fires `tree:getChildren` ~700
57	// log lines before Cocoon's gRPC client finishes handshaking. Without
58	// this wait the first call returns `ClientNotConnected`, the workbench
59	// caches an empty list, and the Explorer never recovers without a manual
60	// refresh. 5000 ms chosen from boot-trace observation.
61	let _ = crate::Vine::Client::WaitForClientConnection::Fn("cocoon-main", 5000).await;
62
63	match crate::Vine::Client::SendRequest::Fn(
64		"cocoon-main",
65		"$provideTreeChildren".to_string(),
66		Parameters,
67		// 5000 ms: real cold-boot tree calls take 700-2200 ms
68		// ([DEV:TREE-LATENCY] clangd.ast=2181, gitlens=1652, npm=1560).
69		5000,
70	)
71	.await
72	{
73		Ok(Value_) => {
74			match &Value_ {
75				Value::Object(_) | Value::Array(_) => Ok(Value_),
76
77				// Non-conforming shape: force to {items:[]} so the renderer
78				// always has iterable data and avoids TypeError crashes.
79				_ => Ok(json!({ "items": [] })),
80			}
81		},
82
83		Err(Error) => {
84			// Log first failure per view; silence repeats so the dev log
85			// doesn't fill with identical lines while the user browses
86			// nodes from a misbehaving extension.
87			crate::IPC::DevLog::DebugOnce::Fn(
88				"tree-view",
89				&format!("get-children-error:{}", ViewId),
90				&format!(
91					"[TreeView] invoke:getChildren error view={} err={:?} (further occurrences silenced)",
92					ViewId, Error
93				),
94			);
95
96			Ok(json!({ "items": [] }))
97		},
98	}
99}