Skip to content

Commit 829b6a7

Browse files
mgoldenbergHywan
authored andcommitted
feat(indexeddb): add indexeddb event cache store impl (backed by memory store)
Signed-off-by: Michael Goldenberg <[email protected]>
1 parent 7b2cd8e commit 829b6a7

File tree

2 files changed

+279
-3
lines changed

2 files changed

+279
-3
lines changed

crates/matrix-sdk-indexeddb/src/event_cache_store/error.rs

Lines changed: 15 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -12,7 +12,10 @@
1212
// See the License for the specific language governing permissions and
1313
// limitations under the License
1414

15-
use matrix_sdk_base::{SendOutsideWasm, SyncOutsideWasm};
15+
use matrix_sdk_base::{
16+
event_cache::store::{EventCacheStore, EventCacheStoreError, MemoryStore},
17+
SendOutsideWasm, SyncOutsideWasm,
18+
};
1619
use thiserror::Error;
1720

1821
/// A trait that combines the necessary traits needed for asynchronous runtimes,
@@ -27,6 +30,8 @@ impl<T> AsyncErrorDeps for T where T: std::error::Error + SendOutsideWasm + Sync
2730
pub enum IndexeddbEventCacheStoreError {
2831
#[error("DomException {name} ({code}): {message}")]
2932
DomException { name: String, message: String, code: u16 },
33+
#[error("media store: {0}")]
34+
MemoryStore(<MemoryStore as EventCacheStore>::Error),
3035
}
3136

3237
impl From<web_sys::DomException> for IndexeddbEventCacheStoreError {
@@ -38,3 +43,12 @@ impl From<web_sys::DomException> for IndexeddbEventCacheStoreError {
3843
}
3944
}
4045
}
46+
47+
impl From<IndexeddbEventCacheStoreError> for EventCacheStoreError {
48+
fn from(value: IndexeddbEventCacheStoreError) -> Self {
49+
match value {
50+
IndexeddbEventCacheStoreError::DomException { .. } => Self::Backend(Box::new(value)),
51+
IndexeddbEventCacheStoreError::MemoryStore(inner) => inner,
52+
}
53+
}
54+
}

crates/matrix-sdk-indexeddb/src/event_cache_store/mod.rs

Lines changed: 264 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -15,10 +15,27 @@
1515
#![allow(unused)]
1616

1717
use indexed_db_futures::IdbDatabase;
18-
use matrix_sdk_base::event_cache::store::MemoryStore;
18+
use matrix_sdk_base::{
19+
event_cache::{
20+
store::{
21+
media::{IgnoreMediaRetentionPolicy, MediaRetentionPolicy},
22+
EventCacheStore, MemoryStore,
23+
},
24+
Event, Gap,
25+
},
26+
linked_chunk::{
27+
ChunkIdentifier, ChunkIdentifierGenerator, ChunkMetadata, LinkedChunkId, Position,
28+
RawChunk, Update,
29+
},
30+
media::MediaRequestParameters,
31+
};
32+
use ruma::{events::relation::RelationType, EventId, MxcUri, OwnedEventId, RoomId};
1933
use web_sys::IdbTransactionMode;
2034

21-
use crate::event_cache_store::serializer::IndexeddbEventCacheStoreSerializer;
35+
use crate::event_cache_store::{
36+
serializer::IndexeddbEventCacheStoreSerializer,
37+
transaction::IndexeddbEventCacheStoreTransaction,
38+
};
2239

2340
mod builder;
2441
mod error;
@@ -56,3 +73,248 @@ impl IndexeddbEventCacheStore {
5673
IndexeddbEventCacheStoreBuilder::default()
5774
}
5875
}
76+
77+
// Small hack to have the following macro invocation act as the appropriate
78+
// trait impl block on wasm, but still be compiled on non-wasm as a regular
79+
// impl block otherwise.
80+
//
81+
// The trait impl doesn't compile on non-wasm due to unfulfilled trait bounds,
82+
// this hack allows us to still have most of rust-analyzer's IDE functionality
83+
// within the impl block without having to set it up to check things against
84+
// the wasm target (which would disable many other parts of the codebase).
85+
#[cfg(target_arch = "wasm32")]
86+
macro_rules! impl_event_cache_store {
87+
( $($body:tt)* ) => {
88+
#[async_trait::async_trait(?Send)]
89+
impl EventCacheStore for IndexeddbEventCacheStore {
90+
type Error = IndexeddbEventCacheStoreError;
91+
92+
$($body)*
93+
}
94+
};
95+
}
96+
97+
#[cfg(not(target_arch = "wasm32"))]
98+
macro_rules! impl_event_cache_store {
99+
( $($body:tt)* ) => {
100+
impl IndexeddbEventCacheStore {
101+
$($body)*
102+
}
103+
};
104+
}
105+
106+
impl_event_cache_store! {
107+
async fn try_take_leased_lock(
108+
&self,
109+
lease_duration_ms: u32,
110+
key: &str,
111+
holder: &str,
112+
) -> Result<bool, IndexeddbEventCacheStoreError> {
113+
self.memory_store
114+
.try_take_leased_lock(lease_duration_ms, key, holder)
115+
.await
116+
.map_err(IndexeddbEventCacheStoreError::MemoryStore)
117+
}
118+
119+
async fn handle_linked_chunk_updates(
120+
&self,
121+
linked_chunk_id: LinkedChunkId<'_>,
122+
updates: Vec<Update<Event, Gap>>,
123+
) -> Result<(), IndexeddbEventCacheStoreError> {
124+
self.memory_store
125+
.handle_linked_chunk_updates(linked_chunk_id, updates)
126+
.await
127+
.map_err(IndexeddbEventCacheStoreError::MemoryStore)
128+
}
129+
130+
async fn load_all_chunks(
131+
&self,
132+
linked_chunk_id: LinkedChunkId<'_>,
133+
) -> Result<Vec<RawChunk<Event, Gap>>, IndexeddbEventCacheStoreError> {
134+
self.memory_store
135+
.load_all_chunks(linked_chunk_id)
136+
.await
137+
.map_err(IndexeddbEventCacheStoreError::MemoryStore)
138+
}
139+
140+
async fn load_all_chunks_metadata(
141+
&self,
142+
linked_chunk_id: LinkedChunkId<'_>,
143+
) -> Result<Vec<ChunkMetadata>, IndexeddbEventCacheStoreError> {
144+
self.memory_store
145+
.load_all_chunks_metadata(linked_chunk_id)
146+
.await
147+
.map_err(IndexeddbEventCacheStoreError::MemoryStore)
148+
}
149+
150+
async fn load_last_chunk(
151+
&self,
152+
linked_chunk_id: LinkedChunkId<'_>,
153+
) -> Result<
154+
(Option<RawChunk<Event, Gap>>, ChunkIdentifierGenerator),
155+
IndexeddbEventCacheStoreError,
156+
> {
157+
self.memory_store
158+
.load_last_chunk(linked_chunk_id)
159+
.await
160+
.map_err(IndexeddbEventCacheStoreError::MemoryStore)
161+
}
162+
163+
async fn load_previous_chunk(
164+
&self,
165+
linked_chunk_id: LinkedChunkId<'_>,
166+
before_chunk_identifier: ChunkIdentifier,
167+
) -> Result<Option<RawChunk<Event, Gap>>, IndexeddbEventCacheStoreError> {
168+
self.memory_store
169+
.load_previous_chunk(linked_chunk_id, before_chunk_identifier)
170+
.await
171+
.map_err(IndexeddbEventCacheStoreError::MemoryStore)
172+
}
173+
174+
async fn clear_all_linked_chunks(&self) -> Result<(), IndexeddbEventCacheStoreError> {
175+
self.memory_store
176+
.clear_all_linked_chunks()
177+
.await
178+
.map_err(IndexeddbEventCacheStoreError::MemoryStore)
179+
}
180+
181+
async fn filter_duplicated_events(
182+
&self,
183+
linked_chunk_id: LinkedChunkId<'_>,
184+
events: Vec<OwnedEventId>,
185+
) -> Result<Vec<(OwnedEventId, Position)>, IndexeddbEventCacheStoreError> {
186+
self.memory_store
187+
.filter_duplicated_events(linked_chunk_id, events)
188+
.await
189+
.map_err(IndexeddbEventCacheStoreError::MemoryStore)
190+
}
191+
192+
async fn find_event(
193+
&self,
194+
room_id: &RoomId,
195+
event_id: &EventId,
196+
) -> Result<Option<Event>, IndexeddbEventCacheStoreError> {
197+
self.memory_store
198+
.find_event(room_id, event_id)
199+
.await
200+
.map_err(IndexeddbEventCacheStoreError::MemoryStore)
201+
}
202+
203+
async fn find_event_relations(
204+
&self,
205+
room_id: &RoomId,
206+
event_id: &EventId,
207+
filters: Option<&[RelationType]>,
208+
) -> Result<Vec<(Event, Option<Position>)>, IndexeddbEventCacheStoreError> {
209+
self.memory_store
210+
.find_event_relations(room_id, event_id, filters)
211+
.await
212+
.map_err(IndexeddbEventCacheStoreError::MemoryStore)
213+
}
214+
215+
async fn save_event(
216+
&self,
217+
room_id: &RoomId,
218+
event: Event,
219+
) -> Result<(), IndexeddbEventCacheStoreError> {
220+
self.memory_store
221+
.save_event(room_id, event)
222+
.await
223+
.map_err(IndexeddbEventCacheStoreError::MemoryStore)
224+
}
225+
226+
async fn add_media_content(
227+
&self,
228+
request: &MediaRequestParameters,
229+
content: Vec<u8>,
230+
ignore_policy: IgnoreMediaRetentionPolicy,
231+
) -> Result<(), IndexeddbEventCacheStoreError> {
232+
self.memory_store
233+
.add_media_content(request, content, ignore_policy)
234+
.await
235+
.map_err(IndexeddbEventCacheStoreError::MemoryStore)
236+
}
237+
238+
async fn replace_media_key(
239+
&self,
240+
from: &MediaRequestParameters,
241+
to: &MediaRequestParameters,
242+
) -> Result<(), IndexeddbEventCacheStoreError> {
243+
self.memory_store
244+
.replace_media_key(from, to)
245+
.await
246+
.map_err(IndexeddbEventCacheStoreError::MemoryStore)
247+
}
248+
249+
async fn get_media_content(
250+
&self,
251+
request: &MediaRequestParameters,
252+
) -> Result<Option<Vec<u8>>, IndexeddbEventCacheStoreError> {
253+
self.memory_store
254+
.get_media_content(request)
255+
.await
256+
.map_err(IndexeddbEventCacheStoreError::MemoryStore)
257+
}
258+
259+
async fn remove_media_content(
260+
&self,
261+
request: &MediaRequestParameters,
262+
) -> Result<(), IndexeddbEventCacheStoreError> {
263+
self.memory_store
264+
.remove_media_content(request)
265+
.await
266+
.map_err(IndexeddbEventCacheStoreError::MemoryStore)
267+
}
268+
269+
async fn get_media_content_for_uri(
270+
&self,
271+
uri: &MxcUri,
272+
) -> Result<Option<Vec<u8>>, IndexeddbEventCacheStoreError> {
273+
self.memory_store
274+
.get_media_content_for_uri(uri)
275+
.await
276+
.map_err(IndexeddbEventCacheStoreError::MemoryStore)
277+
}
278+
279+
async fn remove_media_content_for_uri(
280+
&self,
281+
uri: &MxcUri,
282+
) -> Result<(), IndexeddbEventCacheStoreError> {
283+
self.memory_store
284+
.remove_media_content_for_uri(uri)
285+
.await
286+
.map_err(IndexeddbEventCacheStoreError::MemoryStore)
287+
}
288+
289+
async fn set_media_retention_policy(
290+
&self,
291+
policy: MediaRetentionPolicy,
292+
) -> Result<(), IndexeddbEventCacheStoreError> {
293+
self.memory_store
294+
.set_media_retention_policy(policy)
295+
.await
296+
.map_err(IndexeddbEventCacheStoreError::MemoryStore)
297+
}
298+
299+
fn media_retention_policy(&self) -> MediaRetentionPolicy {
300+
self.memory_store.media_retention_policy()
301+
}
302+
303+
async fn set_ignore_media_retention_policy(
304+
&self,
305+
request: &MediaRequestParameters,
306+
ignore_policy: IgnoreMediaRetentionPolicy,
307+
) -> Result<(), IndexeddbEventCacheStoreError> {
308+
self.memory_store
309+
.set_ignore_media_retention_policy(request, ignore_policy)
310+
.await
311+
.map_err(IndexeddbEventCacheStoreError::MemoryStore)
312+
}
313+
314+
async fn clean_up_media_cache(&self) -> Result<(), IndexeddbEventCacheStoreError> {
315+
self.memory_store
316+
.clean_up_media_cache()
317+
.await
318+
.map_err(IndexeddbEventCacheStoreError::MemoryStore)
319+
}
320+
}

0 commit comments

Comments
 (0)