0508 1.2s轮询同步

This commit is contained in:
lix-2026
2026-05-08 11:23:08 +08:00
parent b183d24ba5
commit 83805f9254
8 changed files with 364 additions and 16 deletions
+23 -15
View File
@@ -693,8 +693,7 @@ pub(crate) fn render_editor_island_adapter_script() -> &'static str {
let lastSavedSerialized = '';
let hasPendingLocalChanges = false;
let suppressNextHostSyncChange = false;
let localExternalPollTimer = 0;
let localExternalPollInFlight = false;
let localExternalEvents = null;
let lastExternalConflictDetectionKey = editorMeta.conflictDetectionKey || '';
const normalizeBridgeValue = (value) => {
if (value instanceof Map) {
@@ -858,10 +857,8 @@ pub(crate) fn render_editor_island_adapter_script() -> &'static str {
setStatus('synced-external-change');
};
const pollLocalMarkdownExternalChange = async () => {
const refreshFromExternalFileChange = async () => {
if (bootstrap.sourceKind !== 'local_folder' || !bootstrap.rootUri || document.hidden) return;
if (localExternalPollInFlight) return;
localExternalPollInFlight = true;
try {
const response = await fetch(pageAggregateUrl().toString(), {
cache: 'no-store',
@@ -883,11 +880,25 @@ pub(crate) fn render_editor_island_adapter_script() -> &'static str {
dispatchReplaceContent(nextAggregate);
} catch (error) {
console.warn('mnote local folder 外部更新检测失败', error);
} finally {
localExternalPollInFlight = false;
}
};
const connectLocalMarkdownExternalEvents = () => {
if (bootstrap.sourceKind !== 'local_folder' || !bootstrap.rootUri || typeof window.EventSource !== 'function') {
return;
}
const url = new URL('/api/local-folder/events', window.location.origin);
url.searchParams.set('rootUri', bootstrap.rootUri);
url.searchParams.set('documentId', bootstrap.documentId);
localExternalEvents = new EventSource(url.toString());
localExternalEvents.addEventListener('change', () => {
void refreshFromExternalFileChange();
});
localExternalEvents.onerror = () => {
console.warn('mnote local folder 外部更新事件流中断,将等待浏览器自动重连');
};
};
const start = async () => {
setStatus('loading-assets');
const manifestResponse = await fetch('/api/leptos-tiptap-runtime/manifest.json', { cache: 'no-store' });
@@ -909,12 +920,7 @@ pub(crate) fn render_editor_island_adapter_script() -> &'static str {
if (typeof window.__mnoteApplyPageOptionsToShell === 'function') {
window.__mnoteApplyPageOptionsToShell();
}
if (bootstrap.sourceKind === 'local_folder' && bootstrap.rootUri) {
void pollLocalMarkdownExternalChange();
localExternalPollTimer = window.setInterval(() => {
void pollLocalMarkdownExternalChange();
}, 1200);
}
connectLocalMarkdownExternalEvents();
setStatus('ready');
};
@@ -1640,10 +1646,12 @@ mod tests {
assert!(html.contains("asset.png"));
assert!(html.contains("data-row-kind=\"markdown\""));
assert!(html.contains("data-mnote-action=\"open-local-folder\""));
assert!(html.contains("pollLocalMarkdownExternalChange"));
assert!(html.contains("/api/page-aggregate/${encodeURIComponent(bootstrap.documentId)}"));
assert!(html.contains("refreshFromExternalFileChange"));
assert!(html.contains("/api/local-folder/events"));
assert!(html.contains("new EventSource(url.toString())"));
assert!(html.contains("command: 'replaceContent'"));
assert!(html.contains("external-change-conflict"));
assert!(!html.contains("setInterval(() => {\n void pollLocalMarkdownExternalChange();\n }, 1200);"));
}
#[tokio::test]