Skip to content

Commit b958101

Browse files
authored
create new indexeddb connection for each query on wasm, implement active (#451)
identity in a persistent way, use static context,use different collection for files,fix build
1 parent 1dee549 commit b958101

32 files changed

+554
-205
lines changed

CHANGELOG.md

Lines changed: 9 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -1,5 +1,14 @@
11
# 0.3.1
22

3+
4+
* Persist active Identity to DB for WASM
5+
* Change indexed-db name to "data"
6+
* Use a different indexed-db collection for files, named "files"
7+
* Create a new indexeddb database connection for each query to avoid transaction overlapping
8+
* Removed timezone db api
9+
* Persist base64 string instead of bytes for images, for more efficiency
10+
* Added Retry-sending for Nostr block events
11+
* Added block propagation via Nostr
312
* Added a caching layer for bills, heavily improving performance
413
* Added `error` logs for all errors returned from the API for the WASM version
514
* Added `log_level` to Config, which defaults to `info`
Lines changed: 3 additions & 20 deletions
Original file line numberDiff line numberDiff line change
@@ -1,32 +1,15 @@
11
use crate::util;
2-
use log::error;
32
use serde::Deserialize;
43

5-
/// Documented at https://timezonedb.com/references/get-time-zone
64
#[derive(Deserialize, Debug)]
75
pub struct TimeApi {
86
pub timestamp: u64,
97
}
108

119
impl TimeApi {
1210
pub async fn get_atomic_time() -> Self {
13-
match reqwest::get("https://vip.timezonedb.com/v2.1/get-time-zone?key=AY3Q7V1JPPNX&format=json&fields=timestamp&by=zone&zone=UTC")
14-
.await
15-
{
16-
Err(e) => {
17-
handle_error(e)
18-
},
19-
Ok(result) => result.json().await.unwrap_or_else(|e| {
20-
handle_error(e)
21-
}),
22-
}
11+
let utc_now = util::date::now();
12+
let timestamp = utc_now.timestamp() as u64;
13+
TimeApi { timestamp }
2314
}
2415
}
25-
26-
fn handle_error(e: reqwest::Error) -> TimeApi {
27-
// if there is an error with the API, fall back to local timestamp
28-
error!("Error while fetching atomic time from API: {e}");
29-
let utc_now = util::date::now();
30-
let timestamp = utc_now.timestamp() as u64;
31-
TimeApi { timestamp }
32-
}

crates/bcr-ebill-api/src/service/identity_service.rs

Lines changed: 36 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -11,6 +11,7 @@ use crate::data::{
1111
use crate::persistence::file_upload::FileUploadStoreApi;
1212
use crate::persistence::identity::IdentityChainStoreApi;
1313
use async_trait::async_trait;
14+
use bcr_ebill_core::identity::ActiveIdentityState;
1415
use log::info;
1516
use std::sync::Arc;
1617

@@ -61,6 +62,15 @@ pub trait IdentityServiceApi: Send + Sync {
6162
file_name: &str,
6263
private_key: &str,
6364
) -> Result<Vec<u8>>;
65+
66+
/// gets the currently set identity
67+
async fn get_current_identity(&self) -> Result<ActiveIdentityState>;
68+
69+
/// sets the active identity to the given personal node id
70+
async fn set_current_personal_identity(&self, node_id: &str) -> Result<()>;
71+
72+
/// sets the active identity to the given company node id
73+
async fn set_current_company_identity(&self, node_id: &str) -> Result<()>;
6474
}
6575

6676
/// The identity service is responsible for managing the local identity
@@ -345,6 +355,32 @@ impl IdentityServiceApi for IdentityService {
345355
let decrypted = util::crypto::decrypt_ecies(&read_file, private_key)?;
346356
Ok(decrypted)
347357
}
358+
359+
async fn get_current_identity(&self) -> Result<ActiveIdentityState> {
360+
let active_identity = self.store.get_current_identity().await?;
361+
Ok(active_identity)
362+
}
363+
364+
async fn set_current_personal_identity(&self, node_id: &str) -> Result<()> {
365+
self.store
366+
.set_current_identity(&ActiveIdentityState {
367+
personal: node_id.to_owned(),
368+
company: None,
369+
})
370+
.await?;
371+
Ok(())
372+
}
373+
374+
async fn set_current_company_identity(&self, node_id: &str) -> Result<()> {
375+
let active_identity = self.store.get_current_identity().await?;
376+
self.store
377+
.set_current_identity(&ActiveIdentityState {
378+
personal: active_identity.personal,
379+
company: Some(node_id.to_owned()),
380+
})
381+
.await?;
382+
Ok(())
383+
}
348384
}
349385

350386
#[cfg(test)]

crates/bcr-ebill-api/src/tests/mod.rs

Lines changed: 3 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -13,7 +13,7 @@ pub mod tests {
1313
},
1414
company::{Company, CompanyKeys},
1515
contact::{Contact, ContactType, IdentityPublicData},
16-
identity::{Identity, IdentityWithAll},
16+
identity::{ActiveIdentityState, Identity, IdentityWithAll},
1717
notification::{ActionType, Notification, NotificationType},
1818
util::crypto::BcrKeys,
1919
};
@@ -136,6 +136,8 @@ pub mod tests {
136136
async fn get_key_pair(&self) -> Result<BcrKeys>;
137137
async fn get_or_create_key_pair(&self) -> Result<BcrKeys>;
138138
async fn get_seedphrase(&self) -> Result<String>;
139+
async fn get_current_identity(&self) -> Result<ActiveIdentityState>;
140+
async fn set_current_identity(&self, identity_state: &ActiveIdentityState) -> Result<()>;
139141
}
140142
}
141143

crates/bcr-ebill-core/src/identity.rs

Lines changed: 6 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -46,3 +46,9 @@ impl Identity {
4646
self.name.clone()
4747
}
4848
}
49+
50+
#[derive(Clone, Debug)]
51+
pub struct ActiveIdentityState {
52+
pub personal: String,
53+
pub company: Option<String>,
54+
}

crates/bcr-ebill-core/src/util/mod.rs

Lines changed: 1 addition & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -3,8 +3,8 @@ pub mod date;
33

44
pub use crypto::BcrKeys;
55

6-
use bitcoin::hashes::sha256;
76
use bitcoin::hashes::Hash;
7+
use bitcoin::hashes::sha256;
88
use thiserror::Error;
99
use uuid::Uuid;
1010

crates/bcr-ebill-persistence/Cargo.toml

Lines changed: 2 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -23,6 +23,7 @@ getrandom = { version = "0.3.1", features = ["wasm_js"] } # needed for wasm buil
2323
# Enable "kv-indxdb" only for WebAssembly (wasm32)
2424
[target.'cfg(target_arch = "wasm32")'.dependencies]
2525
surrealdb = { version = "2.2", default-features = false, features = ["kv-indxdb"] }
26+
base64 = "0.22"
2627

2728
# Enable "protocol-ws" for all other targets
2829
[target.'cfg(not(target_arch = "wasm32"))'.dependencies]
@@ -32,6 +33,7 @@ tokio.workspace = true
3233
[dev-dependencies]
3334
surrealdb = { version = "2.2.0", features = ["kv-mem"], default-features = false }
3435
tokio.workspace = true
36+
base64 = "0.22"
3537

3638
[features]
3739
embedded-db = ["surrealdb/kv-rocksdb"]

crates/bcr-ebill-persistence/src/constants.rs

Lines changed: 14 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -21,3 +21,17 @@ pub const DB_SEARCH_TERM: &str = "search_term";
2121

2222
pub const DB_ENTITY_ID: &str = "entity_id";
2323
pub const DB_FILE_NAME: &str = "file_name";
24+
25+
#[cfg(target_arch = "wasm32")]
26+
pub const SURREAL_DB_CON_INDXDB_DATA: &str = "indxdb://data";
27+
#[cfg(target_arch = "wasm32")]
28+
pub const SURREAL_DB_INDXDB_DB_DATA: &str = "data";
29+
#[cfg(target_arch = "wasm32")]
30+
pub const SURREAL_DB_INDXDB_NS_DATA: &str = "";
31+
32+
#[cfg(target_arch = "wasm32")]
33+
pub const SURREAL_DB_CON_INDXDB_FILES: &str = "indxdb://files";
34+
#[cfg(target_arch = "wasm32")]
35+
pub const SURREAL_DB_INDXDB_DB_FILES: &str = "files";
36+
#[cfg(target_arch = "wasm32")]
37+
pub const SURREAL_DB_INDXDB_NS_FILES: &str = "";

crates/bcr-ebill-persistence/src/db/backup.rs

Lines changed: 20 additions & 3 deletions
Original file line numberDiff line numberDiff line change
@@ -1,5 +1,7 @@
11
use std::path::Path;
22

3+
#[cfg(target_arch = "wasm32")]
4+
use super::get_new_surreal_db;
35
use crate::backup::BackupStoreApi;
46

57
use super::Result;
@@ -8,20 +10,31 @@ use futures::StreamExt;
810
use surrealdb::{Surreal, engine::any::Any};
911

1012
pub struct SurrealBackupStore {
13+
#[allow(dead_code)]
1114
db: Surreal<Any>,
1215
}
1316

1417
impl SurrealBackupStore {
1518
pub fn new(db: Surreal<Any>) -> Self {
1619
Self { db }
1720
}
21+
22+
#[cfg(target_arch = "wasm32")]
23+
async fn db(&self) -> Result<Surreal<Any>> {
24+
get_new_surreal_db().await
25+
}
26+
27+
#[cfg(not(target_arch = "wasm32"))]
28+
async fn db(&self) -> Result<Surreal<Any>> {
29+
Ok(self.db.clone())
30+
}
1831
}
1932

2033
#[async_trait]
2134
impl BackupStoreApi for SurrealBackupStore {
2235
/// returns the whole database as a byte vector backup ready for encryption
2336
async fn backup(&self) -> Result<Vec<u8>> {
24-
let mut stream = self.db.export(()).await?;
37+
let mut stream = self.db().await?.export(()).await?;
2538
let mut buffer = Vec::new();
2639
while let Some(Ok(chunk)) = stream.next().await {
2740
buffer.extend_from_slice(&chunk);
@@ -30,12 +43,16 @@ impl BackupStoreApi for SurrealBackupStore {
3043
}
3144

3245
async fn restore(&self, file_path: &Path) -> Result<()> {
33-
self.db.import(file_path).await?;
46+
self.db().await?.import(file_path).await?;
3447
Ok(())
3548
}
3649

3750
async fn drop_db(&self, name: &str) -> Result<()> {
38-
let _ = self.db.query(format!("REMOVE DATABASE {}", name)).await?;
51+
let _ = self
52+
.db()
53+
.await?
54+
.query(format!("REMOVE DATABASE {}", name))
55+
.await?;
3956
Ok(())
4057
}
4158
}

0 commit comments

Comments
 (0)