refactor(indexeddb): add room-based index to event object store in preparation for linked chunk id as primary key

Signed-off-by: Michael Goldenberg <m@mgoldenberg.net>
This commit is contained in:
Michael Goldenberg
2025-08-15 10:26:53 -04:00
committed by Ivan Enderlin
parent a1c484fb6e
commit 6ff8a26cca
2 changed files with 57 additions and 1 deletions

View File

@@ -118,6 +118,8 @@ pub mod v1 {
pub const LINKED_CHUNKS_NEXT_KEY_PATH: &str = "next";
pub const EVENTS: &str = "events";
pub const EVENTS_KEY_PATH: &str = "id";
pub const EVENTS_ROOM: &str = "events_room";
pub const EVENTS_ROOM_KEY_PATH: &str = "room";
pub const EVENTS_POSITION: &str = "events_position";
pub const EVENTS_POSITION_KEY_PATH: &str = "position";
pub const EVENTS_RELATION: &str = "events_relation";
@@ -169,6 +171,7 @@ pub mod v1 {
/// Create an object store for tracking information about events.
///
/// * Primary Key - `id`
/// * Index (unique) - `room` - tracks whether an event is in a given room
/// * Index (unique) - `position` - tracks position of an event in linked
/// chunks
/// * Index - `relation` - tracks any event to which the given event is
@@ -178,6 +181,14 @@ pub mod v1 {
object_store_params.key_path(Some(&keys::EVENTS_KEY_PATH.into()));
let events = db.create_object_store_with_params(keys::EVENTS, &object_store_params)?;
let events_room_params = IdbIndexParameters::new();
events_room_params.set_unique(true);
events.create_index_with_params(
keys::EVENTS_ROOM,
&keys::EVENTS_ROOM_KEY_PATH.into(),
&events_room_params,
);
let events_position_params = IdbIndexParameters::new();
events_position_params.set_unique(true);
events.create_index_with_params(

View File

@@ -448,6 +448,9 @@ impl<'a> IndexedPrefixKeyComponentBounds<'a, Chunk, &'a RoomId> for IndexedNextC
pub struct IndexedEvent {
/// The primary key of the object store.
pub id: IndexedEventIdKey,
/// An indexed key on the object store, which represents the room in which
/// the event exists
pub room: IndexedEventRoomKey,
/// An indexed key on the object store, which represents the position of the
/// event, if it is in a chunk.
pub position: Option<IndexedEventPositionKey>,
@@ -478,6 +481,7 @@ impl Indexed for Event {
) -> Result<Self::IndexedType, Self::Error> {
let event_id = self.event_id().ok_or(Self::Error::NoEventId)?;
let id = IndexedEventIdKey::encode((self.room_id(), &event_id), serializer);
let room = IndexedEventRoomKey::encode((self.room_id(), &event_id), serializer);
let position = self.position().map(|position| {
IndexedEventPositionKey::encode((self.room_id(), position), serializer)
});
@@ -487,7 +491,13 @@ impl Indexed for Event {
serializer,
)
});
Ok(IndexedEvent { id, position, relation, content: serializer.maybe_encrypt_value(self)? })
Ok(IndexedEvent {
id,
room,
position,
relation,
content: serializer.maybe_encrypt_value(self)?,
})
}
fn from_indexed(
@@ -530,6 +540,41 @@ impl IndexedPrefixKeyBounds<Event, &RoomId> for IndexedEventIdKey {
pub type IndexedEventId = String;
/// The value associated with the [primary key](IndexedEvent::id) of the
/// [`EVENTS`][1] object store, which is constructed from:
///
/// - The (possibly) encrypted Room ID
/// - The (possibly) encrypted Event ID.
///
/// [1]: crate::event_cache_store::migrations::v1::create_events_object_store
#[derive(Debug, Serialize, Deserialize)]
pub struct IndexedEventRoomKey(IndexedRoomId, IndexedEventId);
impl IndexedKey<Event> for IndexedEventRoomKey {
const INDEX: Option<&'static str> = Some(keys::EVENTS_ROOM);
type KeyComponents<'a> = (&'a RoomId, &'a EventId);
fn encode(
(room_id, event_id): Self::KeyComponents<'_>,
serializer: &IndexeddbSerializer,
) -> Self {
let room_id = serializer.encode_key_as_string(keys::ROOMS, room_id.as_str());
let event_id = serializer.encode_key_as_string(keys::EVENTS, event_id);
Self(room_id, event_id)
}
}
impl IndexedPrefixKeyBounds<Event, &RoomId> for IndexedEventRoomKey {
fn lower_key_with_prefix(room_id: &RoomId, serializer: &IndexeddbSerializer) -> Self {
Self::encode((room_id, &*INDEXED_KEY_LOWER_EVENT_ID), serializer)
}
fn upper_key_with_prefix(room_id: &RoomId, serializer: &IndexeddbSerializer) -> Self {
Self::encode((room_id, &*INDEXED_KEY_UPPER_EVENT_ID), serializer)
}
}
/// The value associated with the [`position`](IndexedEvent::position) index of
/// the [`EVENTS`][1] object store, which is constructed from:
///