[feature] cloud sync: cross-device freshness, dirty re-push, streamed download - #50
Merged
Merged
Conversation
… audio download Closes the three deferred multi-device/perf gaps from the sync review. 1. Cross-device staleness (#1): a new localStorage side-channel (src/lib/cloud/ syncState.ts) records, per entry, the cloud updatedAt the local copy matches. listMergedHistory now marks an entry "stale" when the cloud is strictly newer (another device re-analyzed it) and not locally dirty; opening a stale card re-pulls it first. Existing synced entries backfill as synced on first sight, so nothing flips stale spuriously. New amber RefreshCw badge + i18n. 2. Stale-cloud repair (#2): save/re-analyze marks the entry dirty (cleared on a confirmed push), so a failed inline push is retried by the background sweep — which now pushes missing OR dirty entries, skips the pass if the cloud list fails, and aborts on the first auth failure instead of hammering every entry. 3. Download perf (#3): save_remote_history_entry is now async and fetches the audio itself (reqwest, bearer auth), streaming it to disk — the multi-MB blob no longer crosses the JS<->Rust IPC as a JSON number[]. Single-device behavior is unchanged: entries are pushed-then-synced immediately (never stale, never dirty-after-push), and downloads only happen for cloud-only/ stale cards, which don't arise on one device.
…-safe backfill, serialized pushes From the adversarial review of the multi-device sync: - save_remote_history_entry fetches the audio BEFORE writing anything, so a failed download leaves nothing partial (new cloud-only entry) and doesn't disturb the existing files (stale re-pull) — kills the phantom-audio / mutated-good-copy corruption (was HIGH). - renameHistoryEntry now pushes via pushToCloud (marks dirty), so a failed rename push is retried by the sweep instead of leaving the cloud title stale. - listMergedHistory's first-sight backfill no longer clears a live dirty flag (would have dropped a pending re-push and shown the entry falsely synced). - pushLocalEntry is serialized per id, so two concurrent same-id pushes can't complete out of order and record stale content as synced. Deferred nits: download records the list-snapshot updatedAt (one redundant re-pull on a concurrent remote bump); localStorage eviction can mask staleness; res.bytes() buffers the blob (still off the IPC). All cosmetic/best-effort. tsc + cargo check + 79 tests green.
|
❌ The last analysis has failed. |
3 tasks
This file contains hidden or bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
Sign up for free
to join this conversation on GitHub.
Already have an account?
Sign in to comment
Add this suggestion to a batch that can be applied as a single commit.This suggestion is invalid because no changes were made to the code.Suggestions cannot be applied while the pull request is closed.Suggestions cannot be applied while viewing a subset of changes.Only one suggestion per line can be applied in a batch.Add this suggestion to a batch that can be applied as a single commit.Applying suggestions on deleted lines is not supported.You must change the existing code in this line in order to create a valid suggestion.Outdated suggestions cannot be applied.This suggestion has been applied or marked resolved.Suggestions cannot be applied from pending reviews.Suggestions cannot be applied on multi-line comments.Suggestions cannot be applied while the pull request is queued to merge.Suggestion cannot be applied right now. Please check back later.
Closes the three deferred multi-device/perf gaps from the earlier sync review (reviewed adversarially; fixes folded in).
What
src/lib/cloud/syncState.ts(localStorage) records the cloudupdatedAteach local copy matches.listMergedHistorymarks an entry stale (amber ↻) when the cloud is strictly newer (another device re-analyzed it); opening it re-pulls first. Existing entries backfill as synced so nothing flips spuriously.save_remote_history_entryis async and fetches the audio itself (reqwest, bearer) — off the JS↔Rust IPC.Review fixes folded in
dirtyflag.Single-device behavior is unchanged (push→synced immediately; downloads only for cloud-only/stale cards, which don't arise on one device). tsc + cargo check + 79 tests green.