Host: the store's commands (install links, dropped files, the signed Store, the install screen) are served for every app that sets AppConfig::with_store; commands::STORE, testkit::assert_shell_only_group and assert_store_guards

This commit is contained in:
CRTkafa 2026-10-01 03:40:37 +07:00
parent 6e290a357d
commit 266a2f43c1
5 changed files with 230 additions and 6 deletions

View file

@ -80,6 +80,10 @@ pub struct AppConfig {
pub plugins: &'static PluginHost,
/// The home page before the owner sets one (default: the site's first origin).
pub home_url: Option<&'static str>,
/// The store this app installs themes and plugins from (`waybetter://install` links, dropped
/// files, the signed catalog): serves [`commands::STORE`]. Needs `deep_link` for the links and
/// the `net` feature for downloads.
pub store: Option<&'static crate::store::StoreConfig>,
}
impl AppConfig {
@ -101,9 +105,16 @@ impl AppConfig {
page_string_prefixes: &["kit.", "plugin."],
plugins,
home_url: None,
store: None,
}
}
/// Serves the store's commands ([`commands::STORE`]) with this configuration.
pub const fn with_store(mut self, store: &'static crate::store::StoreConfig) -> Self {
self.store = Some(store);
self
}
/// The home page before the owner sets one.
pub fn home(&self) -> String {
self.home_url.map(str::to_owned).unwrap_or_else(|| format!("{}/", self.site.primary_origin()))
@ -1061,6 +1072,17 @@ fn host_handler() -> impl Fn(tauri::ipc::Invoke<Wry>) -> bool + Send + Sync + 's
]
}
/// The store's commands ([`commands::STORE`]): with the `net` feature (downloads) only.
#[cfg(feature = "net")]
fn store_handler() -> impl Fn(tauri::ipc::Invoke<Wry>) -> bool + Send + Sync + 'static {
crate::store_commands::handler()
}
#[cfg(not(feature = "net"))]
fn store_handler() -> impl Fn(tauri::ipc::Invoke<Wry>) -> bool + Send + Sync + 'static {
|_| false
}
type Setup = Box<dyn FnOnce(&AppHandle) -> Result<(), Box<dyn std::error::Error>> + Send>;
/// The app builder: config, site hooks, the app's own setup, then [`App::run`].
@ -1091,6 +1113,7 @@ impl App {
{
let App { config, hooks, setup } = self;
let host_handler = host_handler();
let store_handler = store_handler();
let builder = tauri::Builder::<Wry>::default()
// Must be first: a second launch focuses the running window instead of fighting over
// the app's data and WebView profile (and hands over its link).
@ -1168,6 +1191,8 @@ impl App {
});
tauri_app.manage(Page(Mutex::new(PageState { plugins, features, settings, modes })));
tauri_app.manage(Host { config, hooks });
#[cfg(feature = "net")]
crate::store_commands::init(&handle, &config);
// Safe mode for this run: the launch argument, or Shift held while starting (Windows).
crate::safe::set(crate::safe::at_launch(std::env::args(), host::shift_held()));
#[cfg(debug_assertions)]
@ -1178,7 +1203,9 @@ impl App {
open_window(tauri_app, &config)
})
.invoke_handler(move |invoke| {
if commands::is_host(invoke.message.command()) {
if commands::STORE.contains(&invoke.message.command()) {
store_handler(invoke)
} else if commands::is_host(invoke.message.command()) {
host_handler(invoke)
} else {
handler(invoke)