Repo.import
Use case: I've got a local first app that allows the user to export the automerge file for backup purposes. Doing so doesn't change the doc's ID, so I embed that ID in the doc itself. If the user ever imports the doc, ideally it has the same ID. The automerge-repo impl provides Repo.import, which allows the doc ID to be specified, solving the problem nicely.
Using samod, I resorted to a hack that amounts to writing to IndexDB directly with a "samod-compatible" file name and contents. See code below, which uses my own SamodStorage IndexDB impl.
See https://automerge.org/automerge-repo/classes/_automerge_automerge-repo.Repo.html#import
Repo.delete
Use case: in a local first app it seems like a good idea to allow the user to delete their data. :-)
See https://automerge.org/automerge-repo/classes/_automerge_automerge-repo.Repo.html#delete
P.S. here is the code for my "hack"
/// Explicitly inject a document into the underlying WASM storage with a known ID.
/// This bypasses `repo.create()` which forces a new random ID.
#[cfg(target_arch = "wasm32")]
async fn inject_existing_doc(
repo: samod::Repo,
id: DocumentId,
doc: &automerge::Automerge,
) -> Result<(samod::DocHandle, DocumentId)> {
// This code is a hack to work around the fact that we can't create a
// document with a known ID. TODO: Remove this hack if Samod ever
// has a Repo.inject facility.
//
// The problem is that `repo.create()` always generates a new random ID,
// but we need to create a document with a specific ID (the one passed
// in as an argument).
//
// The solution is to manually inject the document into storage and then
// find it via `repo.find()`.
use crate::samod_storage::SamodStorage;
use samod::storage::{LocalStorage, StorageKey};
let hash = samod_core::CompactionHash::new(&doc.get_heads());
let samod_id: samod::DocumentId = id.into();
let key = StorageKey::snapshot_path(&samod_id, &hash);
// Manually inject into storage to bypass Repo::create generating a new ID
let storage = SamodStorage::new("tasklens_samod", "documents");
storage.put(key, doc.save()).await;
// Now find it via Repo (which should look in storage)
match Self::find_doc(repo, id).await {
Ok(Some(handle)) => Ok((handle, id)),
Ok(None) => Err(anyhow!(
"Document {} not found after manual storage injection",
id
)),
Err(e) => Err(anyhow!(
"Error finding document {} after manual injection: {:?}",
id,
e
)),
}
}
Repo.import
Use case: I've got a local first app that allows the user to export the automerge file for backup purposes. Doing so doesn't change the doc's ID, so I embed that ID in the doc itself. If the user ever imports the doc, ideally it has the same ID. The automerge-repo impl provides
Repo.import, which allows the doc ID to be specified, solving the problem nicely.Using samod, I resorted to a hack that amounts to writing to IndexDB directly with a "samod-compatible" file name and contents. See code below, which uses my own
SamodStorageIndexDB impl.See https://automerge.org/automerge-repo/classes/_automerge_automerge-repo.Repo.html#import
Repo.delete
Use case: in a local first app it seems like a good idea to allow the user to delete their data. :-)
See https://automerge.org/automerge-repo/classes/_automerge_automerge-repo.Repo.html#delete
P.S. here is the code for my "hack"