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 io;
23pub mod macros;
24pub mod model;
25pub mod service;
26pub mod subscribers;
27
28#[derive(Clone)]
29pub struct Lb {
30    pub config: Config,
31    pub user_last_seen: Arc<RwLock<Instant>>,
32    pub keychain: Keychain,
33    pub db: LbDb,
34    pub docs: AsyncDocs,
35    pub client: Network,
36    pub events: EventSubs,
37    pub status: StatusUpdater,
38    pub syncer: Syncer,
39    #[cfg(not(target_family = "wasm"))]
40    pub search: SearchIndex,
41}
42
43impl Lb {
44    /// this is dumb lb that will make the library compile for wasm but doesn't include
45    /// any of the expected functionality. your files wouldn't be saved, sync wouldn't
46    /// work, etc. for now this is useful for unblocking workspace on wasm
47    #[cfg(target_family = "wasm")]
48    pub fn init_dummy(config: Config) -> LbResult<Self> {
49        let db = CoreDb::init(db_rs::Config {
50            path: Default::default(),
51            create_path: false,
52            create_db: false,
53            read_only: false,
54            no_io: true,
55            fs_locks: false,
56            fs_locks_block: false,
57            schema_name: Default::default(),
58        })
59        .map_err(|err| LbErrKind::Unexpected(format!("db rs creation failed: {:#?}", err)))?;
60        let user_last_seen = Arc::new(RwLock::new(Instant::now()));
61
62        Ok(Self {
63            user_last_seen,
64            config: config.clone(),
65            keychain: Default::default(),
66            db: Arc::new(RwLock::new(db)),
67            docs: AsyncDocs::from(&config),
68            client: Default::default(),
69            syncer: Default::default(),
70            events: Default::default(),
71            status: Default::default(),
72        })
73    }
74}
75
76impl Lb {
77    #[instrument(level = "info", skip_all, err(Debug))]
78    pub async fn init(config: Config) -> LbResult<Self> {
79        logging::init(&config)?;
80
81        let docs = AsyncDocs::from(&config);
82        let db_cfg = db_rs::Config::in_folder(&config.writeable_path);
83        let db = CoreDb::init(db_cfg).map_err(|err| LbErrKind::Unexpected(format!("{err:#?}")))?;
84        let keychain = Keychain::from(db.account.get());
85        let db = Arc::new(RwLock::new(db));
86        let client = Network::default();
87        #[cfg(not(target_family = "wasm"))]
88        let search = SearchIndex::default();
89
90        let status = StatusUpdater::default();
91        let syncer = Default::default();
92        let events = EventSubs::default();
93        let user_last_seen = Arc::new(RwLock::new(Instant::now()));
94
95        let result = Self {
96            config,
97            keychain,
98            db,
99            docs,
100            client,
101            syncer,
102            events,
103            status,
104            user_last_seen,
105            #[cfg(not(target_family = "wasm"))]
106            search,
107        };
108
109        #[cfg(not(target_family = "wasm"))]
110        {
111            result.setup_syncer();
112            result.setup_search();
113            result.setup_status().await?;
114        }
115
116        Ok(result)
117    }
118}
119
120pub fn get_code_version() -> &'static str {
121    env!("CARGO_PKG_VERSION")
122}
123
124pub static DEFAULT_API_LOCATION: &str = "https://app.lockbook.net";
125pub static CORE_CODE_VERSION: &str = env!("CARGO_PKG_VERSION");
126
127use crate::io::CoreDb;
128use crate::subscribers::syncer::Syncer;
129use db_rs::Db;
130#[cfg(not(target_family = "wasm"))]
131use subscribers::search::SearchIndex;
132
133use crate::service::logging;
134use io::LbDb;
135use io::docs::AsyncDocs;
136use io::network::Network;
137use model::core_config::Config;
138pub use model::errors::{LbErrKind, LbResult};
139use service::events::EventSubs;
140use service::keychain::Keychain;
141use std::sync::Arc;
142use subscribers::status::StatusUpdater;
143use tokio::sync::RwLock;
144pub use uuid::Uuid;
145use web_time::Instant;