Skip to main content

Mountain/IPC/WindServiceHandlers/NativeHost/
Reload.rs

1//! `nativeHost:reload` - reload the webview without restarting the process.
2//! VS Code calls this from `ILifecycleMainService.reload()` for "Reload
3//! Window" (Developer menu / Cmd+Shift+P → Reload Window).
4//!
5//! Before triggering the renderer reload we ask Cocoon to serialize every
6//! webview panel that has a registered serializer via
7//! `vscode.window.registerWebviewPanelSerializer`. The returned
8//! `(viewType, state)` pairs land in the global memento under
9//! `__webview_panel_state__`, where Sky's webview bridge picks them up
10//! after the reload completes and asks Cocoon to deserialize each entry.
11//!
12//! Errors / timeouts on the serialize path are intentionally swallowed:
13//! reload must remain instant for the operator; a missing panel state
14//! is a survivable degradation, a frozen reload button is not.
15
16use std::{sync::Arc, time::Duration};
17
18use CommonLibrary::Storage::StorageProvider::StorageProvider;
19use serde_json::Value;
20use tauri::{AppHandle, Manager};
21
22use crate::{RunTime::ApplicationRunTime::ApplicationRunTime, dev_log};
23
24const PANEL_STATE_KEY:&str = "__webview_panel_state__";
25
26pub async fn Fn(ApplicationHandle:AppHandle, _Arguments:Vec<Value>) -> Result<Value, String> {
27	dev_log!("lifecycle", "nativeHost:reload - reloading webview");
28
29	// Best-effort webview panel snapshot before the renderer reload wipes
30	// in-memory state. 1.5s budget: a slow serializer can hold up the
31	// reload, but only briefly - past the budget we proceed without state.
32	if ::Vine::Client::IsClientConnected::Fn("cocoon-main") {
33		let SerializeMethod = "ExtHostWebviewPanels$serializeAllWebviewPanels".to_string();
34
35		let SerializeCall =
36			::Vine::Client::SendRequest::Fn("cocoon-main", SerializeMethod, Value::Array(Vec::new()), 1500);
37
38		match tokio::time::timeout(Duration::from_millis(1700), SerializeCall).await {
39			Ok(Ok(Snapshot)) if !Snapshot.is_null() => {
40				if let Some(Runtime) = ApplicationHandle.try_state::<Arc<ApplicationRunTime>>() {
41					if let Err(StoreError) = Runtime
42						.inner()
43						.Environment
44						.UpdateStorageValue(true, PANEL_STATE_KEY.to_string(), Some(Snapshot))
45						.await
46					{
47						dev_log!(
48							"lifecycle",
49							"warn: [Reload] Failed to persist webview panel snapshot: {:?}",
50							StoreError
51						);
52					}
53				}
54			},
55
56			Ok(Ok(_)) => {
57				// Empty / null snapshot - no panels needed serialization.
58			},
59
60			Ok(Err(GrpcError)) => {
61				dev_log!("lifecycle", "warn: [Reload] serializeAllWebviewPanels failed: {:?}", GrpcError);
62			},
63
64			Err(_) => {
65				dev_log!(
66					"lifecycle",
67					"warn: [Reload] serializeAllWebviewPanels timed out - proceeding without panel state"
68				);
69			},
70		}
71	}
72
73	if let Some(Window) = ApplicationHandle.get_webview_window("main") {
74		Window
75			.eval("location.reload()")
76			.map_err(|E| format!("reload eval failed: {E}"))?;
77	}
78
79	Ok(Value::Null)
80}