matrix_sdk_indexeddb/
lib.rs1#![cfg_attr(not(target_family = "wasm"), allow(unused))]
2
3#[cfg(feature = "state-store")]
4use matrix_sdk_base::store::StoreError;
5use thiserror::Error;
6
7#[cfg(feature = "e2e-encryption")]
8mod crypto_store;
9mod error;
10#[cfg(feature = "event-cache-store")]
11mod event_cache_store;
12#[cfg(feature = "media-store")]
13mod media_store;
14mod serializer;
15#[cfg(feature = "state-store")]
16mod state_store;
17#[cfg(any(feature = "event-cache-store", feature = "media-store"))]
18mod transaction;
19
20#[cfg(feature = "e2e-encryption")]
21pub use crypto_store::{IndexeddbCryptoStore, IndexeddbCryptoStoreError};
22#[cfg(feature = "state-store")]
23pub use state_store::{
24 IndexeddbStateStore, IndexeddbStateStoreBuilder, IndexeddbStateStoreError,
25 MigrationConflictStrategy,
26};
27
28#[cfg(feature = "event-cache-store")]
29pub use crate::event_cache_store::{
30 IndexeddbEventCacheStore, IndexeddbEventCacheStoreBuilder, IndexeddbEventCacheStoreError,
31};
32#[cfg(feature = "media-store")]
33pub use crate::media_store::{
34 IndexeddbMediaStore, IndexeddbMediaStoreBuilder, IndexeddbMediaStoreError,
35};
36
37pub struct IndexeddbStores {
43 #[cfg(feature = "e2e-encryption")]
47 pub crypto: IndexeddbCryptoStore,
48 #[cfg(feature = "state-store")]
52 pub state: IndexeddbStateStore,
53 #[cfg(feature = "event-cache-store")]
57 pub event_cache: IndexeddbEventCacheStore,
58 #[cfg(feature = "media-store")]
62 pub media: IndexeddbMediaStore,
63}
64
65impl IndexeddbStores {
66 pub async fn open(
78 name: &str,
79 #[allow(unused_variables)] passphrase: Option<&str>,
80 ) -> Result<Self, OpenStoreError> {
81 #[cfg(all(feature = "e2e-encryption", feature = "state-store"))]
82 if let Some(passphrase) = passphrase {
83 return Self::open_with_passphrase(name, passphrase).await;
84 }
85
86 Self::open_without_passphrase(name).await
87 }
88
89 #[allow(clippy::unused_async)]
95 pub async fn open_without_passphrase(name: &str) -> Result<Self, OpenStoreError> {
96 #[cfg(feature = "state-store")]
97 let state = IndexeddbStateStore::builder()
98 .name(name.to_owned())
99 .build()
100 .await
101 .map_err(StoreError::from)?;
102
103 #[cfg(feature = "e2e-encryption")]
104 let crypto = IndexeddbCryptoStore::open_with_name(name).await?;
105
106 #[cfg(feature = "event-cache-store")]
107 let event_cache = IndexeddbEventCacheStoreBuilder::with_prefix(name).build().await?;
108
109 #[cfg(feature = "media-store")]
110 let media = IndexeddbMediaStoreBuilder::with_prefix(name).build().await?;
111
112 Ok(Self {
113 #[cfg(feature = "state-store")]
114 state,
115 #[cfg(feature = "e2e-encryption")]
116 crypto,
117 #[cfg(feature = "event-cache-store")]
118 event_cache,
119 #[cfg(feature = "media-store")]
120 media,
121 })
122 }
123
124 #[cfg(all(feature = "e2e-encryption", feature = "state-store"))]
134 pub async fn open_with_passphrase(
135 name: &str,
136 passphrase: &str,
137 ) -> Result<Self, OpenStoreError> {
138 let state = IndexeddbStateStore::builder()
139 .name(name.to_owned())
140 .passphrase(passphrase.to_owned())
141 .build()
142 .await
143 .map_err(StoreError::from)?;
144 let store_cipher =
145 state.store_cipher.clone().ok_or(OpenStoreError::FailedToLoadStoreCipher)?;
146
147 let crypto =
148 IndexeddbCryptoStore::open_with_store_cipher(name, Some(store_cipher.clone())).await?;
149
150 #[cfg(feature = "event-cache-store")]
151 let event_cache = IndexeddbEventCacheStoreBuilder::with_prefix(name)
152 .store_cipher(store_cipher.clone())
153 .build()
154 .await?;
155
156 #[cfg(feature = "media-store")]
157 let media = IndexeddbMediaStoreBuilder::with_prefix(name)
158 .store_cipher(store_cipher.clone())
159 .build()
160 .await?;
161
162 Ok(Self {
163 state,
164 crypto,
165 #[cfg(feature = "event-cache-store")]
166 event_cache,
167 #[cfg(feature = "media-store")]
168 media,
169 })
170 }
171}
172
173#[deprecated(
176 note = "this function only opens state and crypto stores, use `IndexeddbStores::open()` instead."
177)]
178#[cfg(all(feature = "e2e-encryption", feature = "state-store"))]
179pub async fn open_stores_with_name(
180 name: &str,
181 passphrase: Option<&str>,
182) -> Result<(IndexeddbStateStore, IndexeddbCryptoStore), OpenStoreError> {
183 let mut builder = IndexeddbStateStore::builder().name(name.to_owned());
184 if let Some(passphrase) = passphrase {
185 builder = builder.passphrase(passphrase.to_owned());
186 }
187
188 let state_store = builder.build().await.map_err(StoreError::from)?;
189 let crypto_store =
190 IndexeddbCryptoStore::open_with_store_cipher(name, state_store.store_cipher.clone())
191 .await?;
192
193 Ok((state_store, crypto_store))
194}
195
196#[cfg(feature = "state-store")]
201pub async fn open_state_store(
202 name: &str,
203 passphrase: Option<&str>,
204) -> Result<IndexeddbStateStore, OpenStoreError> {
205 let mut builder = IndexeddbStateStore::builder().name(name.to_owned());
206 if let Some(passphrase) = passphrase {
207 builder = builder.passphrase(passphrase.to_owned());
208 }
209 let state_store = builder.build().await.map_err(StoreError::from)?;
210
211 Ok(state_store)
212}
213
214#[derive(Error, Debug)]
216pub enum OpenStoreError {
217 #[cfg(feature = "state-store")]
219 #[error(transparent)]
220 State(#[from] StoreError),
221
222 #[cfg(feature = "e2e-encryption")]
224 #[error(transparent)]
225 Crypto(#[from] IndexeddbCryptoStoreError),
226
227 #[cfg(feature = "e2e-encryption")]
232 #[error("failed to load store cipher")]
233 FailedToLoadStoreCipher,
234
235 #[cfg(feature = "event-cache-store")]
237 #[error(transparent)]
238 Event(#[from] IndexeddbEventCacheStoreError),
239
240 #[cfg(feature = "media-store")]
242 #[error(transparent)]
243 Media(#[from] IndexeddbMediaStoreError),
244}