Skip to main content

DevelopmentNodeEnvironment_MicrosoftVSCodeDependency_22NodeVersion_Bundle_Clean_Debug_ElectronProfile_EsbuildCompiler_Mountain/IPC/WindServiceHandlers/TreeView/
GetChildren.rs

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