Skip to main content

lb_rs/
lib.rs

1//! The library that underlies most things [lockbook](https://lockbook.net).
2//!
3//! All lockbook clients
4//! (iOS, linux, etc) rely on this library to perform cryptography, offline edits, and
5//! reconciliation of data between our server, other clients, and other devices.
6//!
7//! Our server relies on this library for checking signatures, and validating whether tree
8//! modifications are valid / authorized.
9//!
10//! - Most clients / integrators will be interested in the functions attached to the [Lb] struct.
11//!   See the [service] module for evolving this functionality.
12//! - The [model] module contains the specification of our data structures and contracts between
13//!   components.
14//! - The [blocking] module contains blocking variants of all [Lb] functions for consumers without
15//!   async runtimes.
16//! - The [io] module contains interactions with disk and network.
17
18#[macro_use]
19extern crate tracing;
20
21pub mod blocking;
22pub mod experiments;
23pub mod io;
24pub mod macros;
25pub mod model;
26pub mod search;
27pub mod service;
28pub mod subscribers;
29#[cfg(target_family = "wasm")]
30pub mod wasm;
31
32#[derive(Clone)]
33pub struct Lb {
34    pub config: Config,
35    pub user_last_seen: Arc<RwLock<Instant>>,
36    pub user_wake: Arc<Notify>,
37    pub keychain: Keychain,
38    pub db: LbDb,
39    pub docs: AsyncDocs,
40    pub client: Network,
41    pub events: EventSubs,
42    pub status: StatusUpdater,
43    pub syncer: Syncer,
44    #[cfg(all(unix, not(target_os = "ios")))]
45    pub(crate) ipc: Arc<Ipc>,
46}
47
48impl Lb {
49    #[instrument(name = "Lb::init", level = "info", skip_all, err(Debug))]
50    pub async fn init(config: Config) -> LbResult<Self> {
51        logging::init(&config)?;
52
53        let docs = AsyncDocs::from(&config);
54        let db = io::init_with_migration(Path::new(&config.writeable_path))
55            .map_err(|err| LbErrKind::Unexpected(format!("{err:#?}")))?;
56        let keychain = Keychain::from(db.schema.account.as_ref());
57        let db = Arc::new(RwLock::new(db));
58        #[cfg(all(unix, not(target_os = "ios")))]
59        let ipc = Arc::new(Ipc::new(&*db.read().await, config.background_work)?);
60        let client = Network { client_type: config.client_type, ..Network::default() };
61
62        let status = StatusUpdater::default();
63        let syncer = Default::default();
64        let events = EventSubs::default();
65        let user_last_seen = Arc::new(RwLock::new(Instant::now()));
66        let user_wake = Arc::new(Notify::new());
67
68        let result = Self {
69            config,
70            keychain,
71            db,
72            docs,
73            client,
74            syncer,
75            events,
76            status,
77            user_last_seen,
78            user_wake,
79            #[cfg(all(unix, not(target_os = "ios")))]
80            ipc,
81        };
82
83        #[cfg(all(unix, not(target_os = "ios")))]
84        result.setup_ipc().await?;
85
86        #[cfg(not(target_family = "wasm"))]
87        {
88            result.setup_syncer();
89            result.setup_status().await?;
90        }
91
92        Ok(result)
93    }
94}
95
96pub fn get_code_version() -> &'static str {
97    env!("CARGO_PKG_VERSION")
98}
99
100pub static DEFAULT_API_LOCATION: &str = "https://app.lockbook.net";
101pub static CORE_CODE_VERSION: &str = env!("CARGO_PKG_VERSION");
102
103#[cfg(all(unix, not(target_os = "ios")))]
104use crate::subscribers::ipc::Ipc;
105use crate::subscribers::syncer::Syncer;
106
107use crate::service::logging;
108use io::LbDb;
109use io::docs::AsyncDocs;
110use io::network::Network;
111use model::core_config::Config;
112pub use model::errors::{LbErrKind, LbResult};
113use service::events::EventSubs;
114use service::keychain::Keychain;
115use std::path::Path;
116use std::sync::Arc;
117use subscribers::status::StatusUpdater;
118use tokio::sync::{Notify, RwLock};
119pub use uuid::Uuid;
120use web_time::Instant;