sos_extension_service/
lib.rs1use sos_account::AccountSwitcherOptions;
2use sos_backend::{BackendTarget, InferOptions};
3use sos_core::{events::changes_feed, Paths};
4use sos_ipc::{
5 extension_helper::server::{
6 ExtensionHelperOptions, ExtensionHelperServer,
7 },
8 ServiceAppInfo,
9};
10use sos_net::{
11 NetworkAccount, NetworkAccountOptions, NetworkAccountSwitcher,
12};
13use std::sync::Arc;
14use tokio::sync::RwLock;
15use xclipboard::Clipboard;
16
17pub async fn run() -> anyhow::Result<()> {
21 let mut args = std::env::args().into_iter().collect::<Vec<_>>();
22
23 #[cfg(windows)]
29 args.pop();
30
31 let extension_id = args.pop().unwrap_or_else(String::new).to_string();
32 let changes_feed = changes_feed();
33
34 let mut accounts =
35 NetworkAccountSwitcher::new_with_options(AccountSwitcherOptions {
36 clipboard: Some(Clipboard::new_timeout(90)?),
37 ..Default::default()
38 });
39
40 let paths = Paths::new_client(Paths::data_dir()?);
41 let target = BackendTarget::infer(paths, InferOptions::default()).await?;
42
43 tracing::info!(backend_target = %target, "extension_service");
44
45 accounts
46 .load_accounts(
47 |identity| {
48 tracing::debug!(
49 account_id = %identity.account_id(),
50 "extension::load_account");
51 Box::pin(async move {
52 let paths = Paths::new_client(Paths::data_dir()?)
53 .with_account_id(identity.account_id());
54 let target =
55 BackendTarget::infer(paths, InferOptions::default())
56 .await?;
57 NetworkAccount::new_unauthenticated(
58 *identity.account_id(),
59 target,
60 NetworkAccountOptions::default(),
61 )
62 .await
63 })
64 },
65 target,
66 )
67 .await?;
68
69 let info = ServiceAppInfo {
70 name: env!("CARGO_PKG_NAME").to_string(),
71 version: env!("CARGO_PKG_VERSION").to_string(),
72 };
73
74 let accounts = Arc::new(RwLock::new(accounts));
75 let options = ExtensionHelperOptions::new(extension_id, info);
76 let server = ExtensionHelperServer::new(options, accounts, |event| {
77 changes_feed.send_replace(event);
78 })
79 .await?;
80 server.listen().await;
81 Ok(())
82}