Store documents as Automerge state
This commit is contained in:
parent
606641dd4a
commit
b01da7be4b
9 changed files with 490 additions and 73 deletions
|
|
@ -2537,12 +2537,15 @@ async fn document_sync_from_peer(
|
|||
if let Some(state) = state {
|
||||
let local = ensure_local_document(&store, name)?;
|
||||
if state.updated_at.0 >= local.updated_at_ms {
|
||||
let normalized = geth_document::normalize_document_state(&state.state_json)?;
|
||||
let merged = geth_document::merge_automerge_states(
|
||||
&local.state_json,
|
||||
&state.state_json,
|
||||
)?;
|
||||
store.insert_document_resource(&StoredDocumentResource {
|
||||
document_id: local.document_id,
|
||||
resource_id: local.resource_id,
|
||||
name: local.name,
|
||||
state_json: normalized,
|
||||
state_json: merged,
|
||||
updated_at_ms: state.updated_at.0,
|
||||
})?;
|
||||
updated = true;
|
||||
|
|
@ -5242,7 +5245,7 @@ async fn handle_iroh_control_connection(
|
|||
bearer_proof.as_ref(),
|
||||
)?;
|
||||
let state = if explanation.allowed && document.updated_at_ms >= since_ms {
|
||||
Some(document_state_from_stored(&document))
|
||||
Some(document_sync_state_from_stored(&document)?)
|
||||
} else {
|
||||
None
|
||||
};
|
||||
|
|
@ -5258,7 +5261,7 @@ async fn handle_iroh_control_connection(
|
|||
reason: explanation.reason,
|
||||
evaluated_ops: explanation.evaluated_ops,
|
||||
nonce,
|
||||
note: "document sync authenticated endpoint/card binding and required document.read on the remote document resource; JSON LWW sync is a bootstrap before Automerge".to_owned(),
|
||||
note: "document sync authenticated endpoint/card binding and required document.read on the remote document resource; durable Automerge state is exchanged with a JSON view for CLI output".to_owned(),
|
||||
}
|
||||
} else {
|
||||
PeerControlResponse::Error {
|
||||
|
|
@ -7430,7 +7433,7 @@ pub fn handle_request(
|
|||
document_id,
|
||||
resource_id,
|
||||
name,
|
||||
state_json: "{}".to_owned(),
|
||||
state_json: geth_document::create_automerge_state("{}")?,
|
||||
updated_at_ms: geth_store::now_ms(),
|
||||
};
|
||||
store.insert_document_resource(&stored)?;
|
||||
|
|
@ -7454,11 +7457,11 @@ pub fn handle_request(
|
|||
let mut stored = store
|
||||
.get_document_resource_by_name(&name)?
|
||||
.ok_or_else(|| NodeError::DocumentNotFound(name.clone()))?;
|
||||
stored.state_json = geth_document::normalize_document_state(&state_json)?;
|
||||
stored.state_json = geth_document::create_automerge_state(&state_json)?;
|
||||
stored.updated_at_ms = geth_store::now_ms();
|
||||
store.insert_document_resource(&stored)?;
|
||||
Ok(ControlResponse::DocumentSet {
|
||||
state: document_state_from_stored(&stored),
|
||||
state: document_state_from_stored(&stored)?,
|
||||
})
|
||||
}
|
||||
ControlRequest::DocumentGet { name } => {
|
||||
|
|
@ -7468,7 +7471,7 @@ pub fn handle_request(
|
|||
.get_document_resource_by_name(&name)?
|
||||
.ok_or_else(|| NodeError::DocumentNotFound(name.clone()))?;
|
||||
Ok(ControlResponse::DocumentGet {
|
||||
state: document_state_from_stored(&stored),
|
||||
state: document_state_from_stored(&stored)?,
|
||||
})
|
||||
}
|
||||
ControlRequest::PubsubPub {
|
||||
|
|
@ -7820,7 +7823,7 @@ fn ensure_local_document(store: &Store, name: &str) -> Result<StoredDocumentReso
|
|||
document_id: format!("document:{name}"),
|
||||
resource_id: format!("resource:document:{name}"),
|
||||
name: name.to_owned(),
|
||||
state_json: "{}".to_owned(),
|
||||
state_json: geth_document::create_automerge_state("{}")?,
|
||||
updated_at_ms: 0,
|
||||
};
|
||||
store.insert_document_resource(&stored)?;
|
||||
|
|
@ -7832,17 +7835,27 @@ fn document_resource_from_stored(stored: &StoredDocumentResource) -> DocumentRes
|
|||
id: stored.document_id.clone().into(),
|
||||
resource: stored.resource_id.clone().into(),
|
||||
name: stored.name.clone(),
|
||||
sync_status: "local-only".to_owned(),
|
||||
state_bytes: stored.state_json.len() as u64,
|
||||
sync_status: "automerge-local".to_owned(),
|
||||
state_bytes: geth_document::document_state_bytes(&stored.state_json),
|
||||
}
|
||||
}
|
||||
|
||||
fn document_state_from_stored(stored: &StoredDocumentResource) -> DocumentState {
|
||||
DocumentState {
|
||||
fn document_state_from_stored(stored: &StoredDocumentResource) -> Result<DocumentState, NodeError> {
|
||||
Ok(DocumentState {
|
||||
document: document_resource_from_stored(stored),
|
||||
state_json: geth_document::document_view_json(&stored.state_json)?,
|
||||
updated_at: UnixMillis(stored.updated_at_ms),
|
||||
})
|
||||
}
|
||||
|
||||
fn document_sync_state_from_stored(
|
||||
stored: &StoredDocumentResource,
|
||||
) -> Result<DocumentState, NodeError> {
|
||||
Ok(DocumentState {
|
||||
document: document_resource_from_stored(stored),
|
||||
state_json: stored.state_json.clone(),
|
||||
updated_at: UnixMillis(stored.updated_at_ms),
|
||||
}
|
||||
})
|
||||
}
|
||||
|
||||
fn file_root_from_stored(stored: &StoredFileRoot) -> FileRoot {
|
||||
|
|
@ -11528,7 +11541,7 @@ mod tests {
|
|||
assert!(allowed);
|
||||
assert!(updated);
|
||||
assert!(reason.contains("direct grant"));
|
||||
assert!(note.contains("JSON LWW"));
|
||||
assert!(note.contains("durable Automerge"));
|
||||
}
|
||||
other => panic!("unexpected allowed document sync response: {other:?}"),
|
||||
}
|
||||
|
|
@ -11804,7 +11817,10 @@ mod tests {
|
|||
left_store
|
||||
.get_document_resource_by_name("notes")
|
||||
.expect("get live-synced document")
|
||||
.map(|document| document.state_json),
|
||||
.map(|document| {
|
||||
geth_document::document_view_json(&document.state_json)
|
||||
.expect("document view json")
|
||||
}),
|
||||
Some(r#"{"title":"live"}"#.to_owned())
|
||||
);
|
||||
let live_remote_root = left_store
|
||||
|
|
|
|||
Loading…
Reference in a new issue