@@ -43,6 +43,8 @@ pub enum IndexeddbEventCacheStoreTransactionError {
43
43
Serialization ( Box < dyn AsyncErrorDeps > ) ,
44
44
#[ error( "item is not unique" ) ]
45
45
ItemIsNotUnique ,
46
+ #[ error( "item not found" ) ]
47
+ ItemNotFound ,
46
48
}
47
49
48
50
impl From < web_sys:: DomException > for IndexeddbEventCacheStoreTransactionError {
@@ -404,6 +406,51 @@ impl<'a> IndexeddbEventCacheStoreTransaction<'a> {
404
406
self . get_item_by_key_components :: < Chunk , IndexedChunkIdKey > ( room_id, chunk_id) . await
405
407
}
406
408
409
+ /// Query IndexedDB for all chunks in the given room
410
+ pub async fn get_chunks_in_room (
411
+ & self ,
412
+ room_id : & RoomId ,
413
+ ) -> Result < Vec < Chunk > , IndexeddbEventCacheStoreTransactionError > {
414
+ self . get_items_in_room :: < Chunk , IndexedChunkIdKey > ( room_id) . await
415
+ }
416
+
417
+ /// Query IndexedDB for given chunk in given room and additionally query
418
+ /// for events or gap, depending on chunk type, in order to construct the
419
+ /// full chunk.
420
+ pub async fn load_chunk_by_id (
421
+ & self ,
422
+ room_id : & RoomId ,
423
+ chunk_id : & ChunkIdentifier ,
424
+ ) -> Result < Option < RawChunk < RawEvent , RawGap > > , IndexeddbEventCacheStoreTransactionError > {
425
+ if let Some ( chunk) = self . get_chunk_by_id ( room_id, chunk_id) . await ? {
426
+ let content = match chunk. chunk_type {
427
+ ChunkType :: Event => {
428
+ let events = self
429
+ . get_events_by_chunk ( room_id, & ChunkIdentifier :: new ( chunk. identifier ) )
430
+ . await ?
431
+ . into_iter ( )
432
+ . map ( RawEvent :: from)
433
+ . collect ( ) ;
434
+ ChunkContent :: Items ( events)
435
+ }
436
+ ChunkType :: Gap => {
437
+ let gap = self
438
+ . get_gap_by_id ( room_id, & ChunkIdentifier :: new ( chunk. identifier ) )
439
+ . await ?
440
+ . ok_or ( IndexeddbEventCacheStoreTransactionError :: ItemNotFound ) ?;
441
+ ChunkContent :: Gap ( RawGap { prev_token : gap. prev_token } )
442
+ }
443
+ } ;
444
+ return Ok ( Some ( RawChunk {
445
+ identifier : ChunkIdentifier :: new ( chunk. identifier ) ,
446
+ content,
447
+ previous : chunk. previous . map ( ChunkIdentifier :: new) ,
448
+ next : chunk. next . map ( ChunkIdentifier :: new) ,
449
+ } ) ) ;
450
+ }
451
+ Ok ( None )
452
+ }
453
+
407
454
/// Add a chunk to the given room and ensure that the next and previous
408
455
/// chunks are properly linked to the chunk being added. If a chunk with
409
456
/// the same identifier already exists, the given chunk will be
@@ -482,6 +529,30 @@ impl<'a> IndexeddbEventCacheStoreTransaction<'a> {
482
529
self . delete_items_in_room :: < Chunk , IndexedChunkIdKey > ( room_id) . await
483
530
}
484
531
532
+ /// Query IndexedDB for events in the given position range in the given
533
+ /// room.
534
+ pub async fn get_events_by_position (
535
+ & self ,
536
+ room_id : & RoomId ,
537
+ range : impl Into < IndexedKeyRange < & Position > > ,
538
+ ) -> Result < Vec < Event > , IndexeddbEventCacheStoreTransactionError > {
539
+ self . get_items_by_key_components :: < Event , IndexedEventPositionKey > ( room_id, range) . await
540
+ }
541
+
542
+ /// Query IndexedDB for events in the given chunk in the given room.
543
+ pub async fn get_events_by_chunk (
544
+ & self ,
545
+ room_id : & RoomId ,
546
+ chunk_id : & ChunkIdentifier ,
547
+ ) -> Result < Vec < Event > , IndexeddbEventCacheStoreTransactionError > {
548
+ let mut lower = IndexedEventPositionKey :: lower_key_components ( ) ;
549
+ lower. chunk_identifier = chunk_id. index ( ) ;
550
+ let mut upper = IndexedEventPositionKey :: upper_key_components ( ) ;
551
+ upper. chunk_identifier = chunk_id. index ( ) ;
552
+ let range = IndexedKeyRange :: Bound ( & lower, & upper) ;
553
+ self . get_events_by_position ( room_id, range) . await
554
+ }
555
+
485
556
/// Puts an event in the given room. If an event with the same key already
486
557
/// exists, it will be overwritten.
487
558
pub async fn put_event (
@@ -557,6 +628,15 @@ impl<'a> IndexeddbEventCacheStoreTransaction<'a> {
557
628
self . delete_items_in_room :: < Event , IndexedEventIdKey > ( room_id) . await
558
629
}
559
630
631
+ /// Query IndexedDB for the gap in the given chunk in the given room.
632
+ pub async fn get_gap_by_id (
633
+ & self ,
634
+ room_id : & RoomId ,
635
+ chunk_id : & ChunkIdentifier ,
636
+ ) -> Result < Option < Gap > , IndexeddbEventCacheStoreTransactionError > {
637
+ self . get_item_by_key_components :: < Gap , IndexedGapIdKey > ( room_id, chunk_id) . await
638
+ }
639
+
560
640
/// Delete gap that matches the given chunk identifier in the given room
561
641
pub async fn delete_gap_by_id (
562
642
& self ,
0 commit comments