Skip to main content

Mountain/IPC/WindServiceHandlers/Extension/
NotifyCocoonDeltaExtensions.rs

1//! Post-install/uninstall Cocoon notification.
2//!
3//! `$deltaExtensions` adds or removes the supplied descriptors from
4//! Cocoon's extension registry and indexes `activationEvents`, but it
5//! does **not** fire those events. The workbench emits
6//! `$activateByEvent("*")` exactly once at boot; anything installed
7//! later never sees its startup events re-fired. This helper bursts the
8//! single always-satisfied activation event (`onStartupFinished`) after
9//! delta so a VSIX with that trigger activates without a reload.
10//!
11//! Fire-and-forget: missing Cocoon (`Spawn=false`) or a
12//! transient RPC failure is logged and swallowed.
13
14use serde_json::{Value, json};
15
16use crate::{Vine, dev_log};
17
18/// Cocoon sidecar identifier; matches
19/// `CocoonManagement::COCOON_SIDE_CAR_IDENTIFIER`.
20const COCOON_SIDE_CAR_IDENTIFIER:&str = "cocoon-main";
21
22/// Timeout for fire-and-forget `$deltaExtensions` notifications; long
23/// enough to survive a busy Cocoon but short enough that install
24/// feedback isn't blocked on a stalled extension host.
25const COCOON_DELTA_TIMEOUT_MS:u64 = 10_000;
26
27pub fn Fn(ToAdd:Vec<Value>, ToRemove:Vec<Value>) {
28	tokio::spawn(async move {
29		let Parameters = json!({
30			"toAdd": ToAdd,
31			"toRemove": ToRemove,
32		});
33
34		match ::Vine::Client::SendRequest::Fn(
35			&COCOON_SIDE_CAR_IDENTIFIER.to_string(),
36			"$deltaExtensions".to_string(),
37			Parameters,
38			COCOON_DELTA_TIMEOUT_MS,
39		)
40		.await
41		{
42			Ok(Response) => {
43				dev_log!("extensions", "$deltaExtensions applied: {}", Response);
44			},
45			Err(Error) => {
46				dev_log!("extensions", "warn: $deltaExtensions failed (non-fatal): {}", Error);
47
48				// Skip the activation burst when delta itself failed.
49				return;
50			},
51		}
52
53		// Only `onStartupFinished` is fired post-delta - the one event
54		// guaranteed to be already satisfied by the time user
55		// interaction could reach the install handler (lifecycle phase
56		// Ready). Firing `"*"` would over-activate lazy extensions.
57		for Event in ["onStartupFinished"] {
58			let ActivationParameters = json!({ "activationEvent": Event });
59
60			match ::Vine::Client::SendRequest::Fn(
61				&COCOON_SIDE_CAR_IDENTIFIER.to_string(),
62				"$activateByEvent".to_string(),
63				ActivationParameters,
64				COCOON_DELTA_TIMEOUT_MS,
65			)
66			.await
67			{
68				Ok(Response) => {
69					dev_log!("extensions", "$activateByEvent({}) post-delta applied: {}", Event, Response);
70				},
71				Err(Error) => {
72					dev_log!(
73						"extensions",
74						"warn: $activateByEvent({}) post-delta failed (non-fatal): {}",
75						Event,
76						Error
77					);
78				},
79			}
80		}
81	});
82}