···212212 pub edit_root: Option<StrongRef<'static>>,
213213 /// StrongRef to the most recent sh.weaver.edit.diff record.
214214 pub last_diff: Option<StrongRef<'static>>,
215215- /// Whether the current doc state is synced with PDS.
216216- /// False if local has changes not yet pushed to PDS.
217217- pub is_synced: bool,
215215+ /// Version vector of the last known PDS state.
216216+ /// Used to determine what changes need to be synced.
217217+ /// None if never synced to PDS.
218218+ pub synced_version: Option<VersionVector>,
218219}
219220220221impl PartialEq for LoadedDocState {
···993994 };
994995 let loro_cursor = content.get_cursor(cursor_offset, Side::default());
995996996996- // Track sync state - if synced, record current version
997997- let last_synced_version = if state.is_synced {
998998- Some(doc.oplog_vv())
999999- } else {
10001000- None
10011001- };
997997+ // Use the synced version from state (tracks the PDS version vector)
998998+ let last_synced_version = state.synced_version;
100299910031000 Self {
10041001 doc,
+21-3
crates/weaver-app/src/components/editor/sync.rs
···671671 entry_ref: local.entry_ref, // Restored from localStorage
672672 edit_root: None,
673673 last_diff: None,
674674- is_synced: false, // Local-only, not synced to PDS
674674+ synced_version: None, // Local-only, never synced to PDS
675675 }))
676676 }
677677···692692 }
693693 }
694694695695+ // Capture the version after loading all PDS state - this is our sync baseline
696696+ let synced_version = Some(doc.oplog_vv());
697697+695698 Ok(Some(LoadedDocState {
696699 doc,
697700 entry_ref: None, // Entry ref comes from the entry itself, not edit state
698701 edit_root: Some(pds.root_ref),
699702 last_diff: pds.last_diff_ref,
700700- is_synced: true, // Just loaded from PDS, fully synced
703703+ synced_version, // Just loaded from PDS, fully synced
701704 }))
702705 }
703706···705708 // Both exist - merge using CRDT
706709 tracing::debug!("Merging document from localStorage and PDS");
707710711711+ // First, reconstruct the PDS state to get its version vector
712712+ let pds_doc = LoroDoc::new();
713713+ if let Err(e) = pds_doc.import(&pds.root_snapshot) {
714714+ tracing::warn!("Failed to import PDS root snapshot for VV: {:?}", e);
715715+ }
716716+ for updates in &pds.diff_updates {
717717+ if let Err(e) = pds_doc.import(updates) {
718718+ tracing::warn!("Failed to apply PDS diff for VV: {:?}", e);
719719+ }
720720+ }
721721+ let pds_version = pds_doc.oplog_vv();
722722+723723+ // Now create the merged doc
708724 let doc = LoroDoc::new();
709725710726 // Import local snapshot first
···724740 }
725741 }
726742743743+ // Use the PDS version as our sync baseline - any local changes
744744+ // beyond this will be detected as unsynced
727745 Ok(Some(LoadedDocState {
728746 doc,
729747 entry_ref: local.entry_ref, // Restored from localStorage
730748 edit_root: Some(pds.root_ref),
731749 last_diff: pds.last_diff_ref,
732732- is_synced: false, // Local had state, may have unsynced changes
750750+ synced_version: Some(pds_version),
733751 }))
734752 }
735753 }