Phase 16G - Word Count Synchronisation Audit and Completion

This commit is contained in:
Nick Beckley 2026-06-27 22:39:29 +01:00
parent 0fc21041fc
commit 507e16165e
2 changed files with 30 additions and 12 deletions

View File

@ -204,6 +204,7 @@
let isAutoRefreshingScene = false; let isAutoRefreshingScene = false;
let sceneWordCountSyncTimer = null; let sceneWordCountSyncTimer = null;
let sceneWordCountSyncInFlight = false; let sceneWordCountSyncInFlight = false;
let sceneWordCountSyncPending = false;
let lastSyncedSceneId = null; let lastSyncedSceneId = null;
let lastSyncedWordCount = null; let lastSyncedWordCount = null;
let lastLinkedSceneTitle = ""; let lastLinkedSceneTitle = "";
@ -3684,7 +3685,17 @@
} }
}; };
const syncSceneProgress = async () => { const finishSceneWordCountSync = () => {
sceneWordCountSyncInFlight = false;
updateSceneActionButtons();
if (sceneWordCountSyncPending) {
sceneWordCountSyncPending = false;
scheduleSceneWordCountSync(1000);
}
};
const syncSceneProgress = async (options = {}) => {
const source = options.source || "manual";
if (!resolvedSceneId) { if (!resolvedSceneId) {
setSyncStatus("No resolved PlotDirector scene."); setSyncStatus("No resolved PlotDirector scene.");
return; return;
@ -3708,11 +3719,14 @@
} }
if (sceneWordCountSyncInFlight) { if (sceneWordCountSyncInFlight) {
sceneWordCountSyncPending = true;
runtimeDebug("Scene sync deferred; sync already running.");
return; return;
} }
clearPendingSceneWordCountSync(); clearPendingSceneWordCountSync();
sceneWordCountSyncInFlight = true; sceneWordCountSyncInFlight = true;
sceneWordCountSyncPending = false;
let wordCount = detectedSceneWordCount; let wordCount = detectedSceneWordCount;
try { try {
@ -3720,31 +3734,34 @@
} catch (error) { } catch (error) {
setSyncStatus("Sync failed"); setSyncStatus("Sync failed");
setDiagnostics({ lastError: errorText(error) }); setDiagnostics({ lastError: errorText(error) });
sceneWordCountSyncInFlight = false; runtimeDebug("Scene sync failed.");
updateSceneActionButtons(); finishSceneWordCountSync();
return; return;
} }
if (!Number.isInteger(wordCount) || wordCount < 0) { if (!Number.isInteger(wordCount) || wordCount < 0) {
setSyncStatus("Sync failed"); setSyncStatus("Sync failed");
sceneWordCountSyncInFlight = false; runtimeDebug("Scene sync failed.");
updateSceneActionButtons(); finishSceneWordCountSync();
return; return;
} }
if (lastSyncedSceneId === resolvedSceneId && lastSyncedWordCount === wordCount) { if (lastSyncedSceneId === resolvedSceneId && lastSyncedWordCount === wordCount) {
setSyncStatus("Synced"); setSyncStatus("Synced");
sceneWordCountSyncInFlight = false; runtimeDebug("Sync skipped (count unchanged).");
updateSceneActionButtons(); finishSceneWordCountSync();
return; return;
} }
runtimeDebug("Scene word count changed.");
if (syncSceneProgressButton) { if (syncSceneProgressButton) {
syncSceneProgressButton.disabled = true; syncSceneProgressButton.disabled = true;
syncSceneProgressButton.textContent = "Syncing..."; syncSceneProgressButton.textContent = "Syncing...";
} }
setSyncStatus("Syncing..."); setSyncStatus("Syncing...");
runtimeDebug(`Scene sync started (${source}).`);
try { try {
const response = await postJson("/api/word-companion/runtime/scene-word-count", { const response = await postJson("/api/word-companion/runtime/scene-word-count", {
documentGuid, documentGuid,
@ -3762,15 +3779,16 @@
setText(syncLastSynced, formatLastSynced(syncedAt)); setText(syncLastSynced, formatLastSynced(syncedAt));
setText(runtimeLastSync, formatLastSynced(syncedAt)); setText(runtimeLastSync, formatLastSynced(syncedAt));
setSyncStatus("Synced"); setSyncStatus("Synced");
runtimeDebug("Scene sync succeeded.");
} catch (error) { } catch (error) {
setSyncStatus("Sync failed"); setSyncStatus("Sync failed");
setDiagnostics({ lastError: errorText(error) }); setDiagnostics({ lastError: errorText(error) });
runtimeDebug("Scene sync failed.");
} finally { } finally {
sceneWordCountSyncInFlight = false;
if (syncSceneProgressButton) { if (syncSceneProgressButton) {
syncSceneProgressButton.textContent = "Sync Current Scene"; syncSceneProgressButton.textContent = "Sync Current Scene";
} }
updateSceneActionButtons(); finishSceneWordCountSync();
} }
}; };
@ -3782,7 +3800,7 @@
sceneWordCountSyncTimer = window.setTimeout(() => { sceneWordCountSyncTimer = window.setTimeout(() => {
sceneWordCountSyncTimer = null; sceneWordCountSyncTimer = null;
void syncSceneProgress(); void syncSceneProgress({ source: "automatic" });
}, delayMs); }, delayMs);
}; };
@ -4495,7 +4513,7 @@
}); });
refreshPlotDirectorSceneButton?.addEventListener("click", refreshPlotDirectorScene); refreshPlotDirectorSceneButton?.addEventListener("click", refreshPlotDirectorScene);
refreshCurrentSceneButton?.addEventListener("click", refreshCurrentScene); refreshCurrentSceneButton?.addEventListener("click", refreshCurrentScene);
syncSceneProgressButton?.addEventListener("click", syncSceneProgress); syncSceneProgressButton?.addEventListener("click", () => syncSceneProgress({ source: "manual" }));
saveSceneLinksButton?.addEventListener("click", saveSceneLinks); saveSceneLinksButton?.addEventListener("click", saveSceneLinks);
attachPlotDirectorIdsButton?.addEventListener("click", attachPlotDirectorIds); attachPlotDirectorIdsButton?.addEventListener("click", attachPlotDirectorIds);
createPlotDirectorChapterButton?.addEventListener("click", createPlotDirectorChapter); createPlotDirectorChapterButton?.addEventListener("click", createPlotDirectorChapter);

File diff suppressed because one or more lines are too long