Skip to content
Closed
Show file tree
Hide file tree
Changes from all commits
Commits
Show all changes
30 commits
Select commit Hold shift + click to select a range
be94205
build(indexeddb): add event-cache-store feature in preparation for mo…
mgoldenberg May 23, 2025
31ab7e1
feat(indexeddb): add event cache store with database initialization l…
mgoldenberg May 6, 2025
b4b15f1
refactor(indexeddb): add Debug impl for IndexeddbSerializer
mgoldenberg May 7, 2025
144ee52
feat(indexeddb): add Debug impl for IndexeddbEventCacheStore
mgoldenberg May 7, 2025
9970df8
feat(indexeddb): add conversion EventCacheStoreError <= IndexeddbEven…
mgoldenberg May 7, 2025
04caadf
feat(indexeddb): add dummy impl of EventCacheStore
mgoldenberg May 7, 2025
f302832
feat(indexeddb): add key encoding logic for event cache store
mgoldenberg May 8, 2025
054b10d
refactor(indexeddb): add internal types for representing linked chunk…
mgoldenberg May 8, 2025
4a0979f
feat(indexeddb): add transparent wrapper type for ensuring (de)serial…
mgoldenberg May 8, 2025
5ef05a4
feat(indexeddb): add impl for IndexeddbEventCacheStore::handle_linked…
mgoldenberg May 9, 2025
9001fa5
feat(indexeddb): add impl for IndexeddbEventCacheStore::load_all_chunks
mgoldenberg May 9, 2025
760b20f
feat(indexeddb): add impl for IndexeddbEventCacheStore::clear_all_roo…
mgoldenberg May 9, 2025
42a6bdc
feat(indexeddb): add impl for IndexeddbEventCacheStore::try_take_leas…
mgoldenberg May 9, 2025
c550b66
feat(indexeddb): use in-memory store for media in event cache
mgoldenberg May 9, 2025
6b1dfdd
refactor(indexeddb): remove unnecessary copy of store cipher in event…
mgoldenberg May 9, 2025
34b5a25
test(indexeddb): add unit and integration tests for event cache store
mgoldenberg May 14, 2025
fb7e60b
feat(indexeddb): add impl for IndexeddbEventCacheStore::load_last_chunk
mgoldenberg May 14, 2025
6902510
feat(indexeddb): add impl for IndexeddbEventCacheStore::load_previous…
mgoldenberg May 15, 2025
fbf7836
feat(indexeddb): add impl for IndexeddbEventCacheStore::find_event
mgoldenberg May 15, 2025
607c660
refactor(indexeddb): track enclosing chunk for timeline events in eve…
mgoldenberg May 15, 2025
8443c01
feat(indexeddb): add impl for IndexeddbEventCacheStore::filter_duplic…
mgoldenberg May 15, 2025
737705a
feat(indexeddb): add impl for IndexeddbEventCacheStore::find_event_re…
mgoldenberg May 15, 2025
a124704
feat(indexeddb): add support for out-of-band events in event cache store
mgoldenberg May 16, 2025
776fc8c
feat(indexeddb): add impl for IndexeddbEventCacheStore::save_event
mgoldenberg May 16, 2025
7a720c1
fix(indexeddb): update event id comparison logic in IndexeddbEventCac…
mgoldenberg May 16, 2025
5aad72b
style(indexeddb): format EventCacheStore impl outside of macro
mgoldenberg May 16, 2025
815bafe
test(indexeddb): copy tests from sqlite event cache store
mgoldenberg May 18, 2025
8d4f37a
fix(indexeddb): detect cycles and disjoint lists in event cache store…
mgoldenberg May 20, 2025
fb8c0e5
fix(indexeddb): distinguish in-band/out-of-band event keys in event c…
mgoldenberg May 23, 2025
1c8941e
test(indexeddb): only run event cache store tests on wasm32
mgoldenberg May 24, 2025
File filter

Filter by extension

Filter by extension


Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
6 changes: 6 additions & 0 deletions crates/matrix-sdk-indexeddb/CHANGELOG.md
Original file line number Diff line number Diff line change
Expand Up @@ -6,6 +6,12 @@ All notable changes to this project will be documented in this file.

## [Unreleased] - ReleaseDate

### Features

- Add `IndexeddbEventCacheStore` for providing an IndexedDB implementation
of the `EventCacheStore`. Expose the type through `IndexeddbEventCacheStoreBuilder`
which ensures object stores in IndexedDB are properly initialized.

## [0.11.0] - 2025-04-11

No notable changes in this release.
Expand Down
14 changes: 11 additions & 3 deletions crates/matrix-sdk-indexeddb/Cargo.toml
Original file line number Diff line number Diff line change
Expand Up @@ -14,9 +14,10 @@ default-target = "wasm32-unknown-unknown"
rustdoc-args = ["--cfg", "docsrs", "--generate-link-to-definition"]

[features]
default = ["e2e-encryption", "state-store"]
default = ["e2e-encryption", "state-store", "event-cache-store"]
state-store = ["dep:matrix-sdk-base", "growable-bloom-filter"]
e2e-encryption = ["dep:matrix-sdk-crypto"]
event-cache-store = ["e2e-encryption"]
testing = ["matrix-sdk-crypto?/testing"]

[dependencies]
Expand Down Expand Up @@ -55,10 +56,17 @@ matrix-sdk-common = { workspace = true, features = ["js"] }
matrix-sdk-crypto = { workspace = true, features = ["js", "testing"] }
matrix-sdk-test.workspace = true
rand.workspace = true
tracing-subscriber = { workspace = true, features = ["registry", "tracing-log"] }
tracing-subscriber = { workspace = true, features = [
"registry",
"tracing-log",
] }
uuid.workspace = true
wasm-bindgen-test.workspace = true
web-sys = { workspace = true, features = ["IdbKeyRange", "Window", "Performance"] }
web-sys = { workspace = true, features = [
"IdbKeyRange",
"Window",
"Performance",
] }

[lints]
workspace = true
47 changes: 47 additions & 0 deletions crates/matrix-sdk-indexeddb/src/event_cache_store/builder.rs
Original file line number Diff line number Diff line change
@@ -0,0 +1,47 @@
use std::sync::Arc;

use matrix_sdk_base::event_cache::store::MemoryStore;
use matrix_sdk_store_encryption::StoreCipher;

use crate::{
event_cache_store::{migrations::open_and_upgrade_db, IndexeddbEventCacheStore, Result},
serializer::IndexeddbSerializer,
};

/// Builder for [`IndexeddbEventCacheStore`]
pub struct IndexeddbEventCacheStoreBuilder {
name: Option<String>,
store_cipher: Option<Arc<StoreCipher>>,
}

impl IndexeddbEventCacheStoreBuilder {
pub fn new() -> Self {
Self { name: None, store_cipher: None }
}

pub fn name(mut self, name: String) -> Self {
self.name = Some(name);
self
}

pub fn store_cipher(mut self, store_cipher: Arc<StoreCipher>) -> Self {
self.store_cipher = Some(store_cipher);
self
}

pub async fn build(self) -> Result<IndexeddbEventCacheStore> {
let name = self.name.unwrap_or_else(|| "event_cache".to_owned());
let store = IndexeddbEventCacheStore {
inner: open_and_upgrade_db(&name).await?,
serializer: IndexeddbSerializer::new(self.store_cipher),
media_store: MemoryStore::new(),
};
Ok(store)
}
}

impl Default for IndexeddbEventCacheStoreBuilder {
fn default() -> Self {
Self::new()
}
}
58 changes: 58 additions & 0 deletions crates/matrix-sdk-indexeddb/src/event_cache_store/migrations.rs
Original file line number Diff line number Diff line change
@@ -0,0 +1,58 @@
// Copyright 2025 The Matrix.org Foundation C.I.C.
//
// Licensed under the Apache License, Version 2.0 (the "License");
// you may not use this file except in compliance with the License.
// You may obtain a copy of the License at
//
// http://www.apache.org/licenses/LICENSE-2.0
//
// Unless required by applicable law or agreed to in writing, software
// distributed under the License is distributed on an "AS IS" BASIS,
// WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
// See the License for the specific language governing permissions and
// limitations under the License

use indexed_db_futures::{
idb_object_store::IdbObjectStoreParameters,
request::{IdbOpenDbRequestLike, OpenDbRequest},
IdbDatabase, IdbKeyPath, IdbVersionChangeEvent,
};
use wasm_bindgen::JsValue;
use web_sys::DomException;

use crate::event_cache_store::keys;

const CURRENT_DB_VERSION: u32 = 2;

pub async fn open_and_upgrade_db(name: &str) -> Result<IdbDatabase, DomException> {
let mut db = IdbDatabase::open(name)?.await?;
let old_version = db.version() as u32;
if old_version == 1 {
db = setup_db(db, CURRENT_DB_VERSION).await?;
}
Ok(db)
}

async fn setup_db(db: IdbDatabase, version: u32) -> Result<IdbDatabase, DomException> {
let name = db.name();
db.close();

let db = {
let mut request: OpenDbRequest = IdbDatabase::open_u32(&name, version)?;
request.set_on_upgrade_needed(Some(
move |events: &IdbVersionChangeEvent| -> Result<(), JsValue> {
events.db().create_object_store(keys::CORE)?;

let mut params = IdbObjectStoreParameters::new();
params.key_path(Some(&IdbKeyPath::from("id")));
events.db().create_object_store_with_params(keys::LINKED_CHUNKS, &params)?;
events.db().create_object_store_with_params(keys::EVENTS, &params)?;
events.db().create_object_store_with_params(keys::GAPS, &params)?;
Ok(())
},
));
request.await?
};

Ok(db)
}
Loading
Loading