Bound document cache size to prevent long-session UI slowdown
This commit is contained in:
parent
cde37b814d
commit
c9c61a279e
@ -58,6 +58,7 @@
|
|||||||
busy: boolean;
|
busy: boolean;
|
||||||
error: string;
|
error: string;
|
||||||
};
|
};
|
||||||
|
const MAX_CACHED_DOCUMENTS = 5;
|
||||||
|
|
||||||
const initialEntry = getDefaultEntry(get(entriesStore));
|
const initialEntry = getDefaultEntry(get(entriesStore));
|
||||||
|
|
||||||
@ -73,6 +74,7 @@
|
|||||||
"# Daily Notes\n\nStart writing today's entry...",
|
"# Daily Notes\n\nStart writing today's entry...",
|
||||||
};
|
};
|
||||||
let savedDocumentContent: Record<string, string> = { ...openDocuments };
|
let savedDocumentContent: Record<string, string> = { ...openDocuments };
|
||||||
|
let documentAccessOrder: string[] = Object.keys(openDocuments);
|
||||||
let modalOpen = false;
|
let modalOpen = false;
|
||||||
let modalTitle = "";
|
let modalTitle = "";
|
||||||
let modalMessage = "";
|
let modalMessage = "";
|
||||||
@ -165,6 +167,41 @@
|
|||||||
return fileName.replace(/\.template\.md$/i, "");
|
return fileName.replace(/\.template\.md$/i, "");
|
||||||
}
|
}
|
||||||
|
|
||||||
|
function touchDocument(id: string) {
|
||||||
|
documentAccessOrder = [
|
||||||
|
...documentAccessOrder.filter((item) => item !== id),
|
||||||
|
id,
|
||||||
|
];
|
||||||
|
}
|
||||||
|
|
||||||
|
function pruneDocumentCache(preserveIds: string[] = []) {
|
||||||
|
const preserve = new Set(
|
||||||
|
preserveIds.filter(Boolean).concat(activeDocumentId ? [activeDocumentId] : []),
|
||||||
|
);
|
||||||
|
const cachedIds = Object.keys(openDocuments);
|
||||||
|
if (cachedIds.length <= MAX_CACHED_DOCUMENTS) return;
|
||||||
|
|
||||||
|
let nextOpen = { ...openDocuments };
|
||||||
|
let nextSaved = { ...savedDocumentContent };
|
||||||
|
let nextOrder = [...documentAccessOrder];
|
||||||
|
let currentSize = cachedIds.length;
|
||||||
|
|
||||||
|
for (const candidate of documentAccessOrder) {
|
||||||
|
if (currentSize <= MAX_CACHED_DOCUMENTS) break;
|
||||||
|
if (preserve.has(candidate)) continue;
|
||||||
|
if (!(candidate in nextOpen)) continue;
|
||||||
|
|
||||||
|
delete nextOpen[candidate];
|
||||||
|
delete nextSaved[candidate];
|
||||||
|
nextOrder = nextOrder.filter((item) => item !== candidate);
|
||||||
|
currentSize -= 1;
|
||||||
|
}
|
||||||
|
|
||||||
|
openDocuments = nextOpen;
|
||||||
|
savedDocumentContent = nextSaved;
|
||||||
|
documentAccessOrder = nextOrder;
|
||||||
|
}
|
||||||
|
|
||||||
function showModal(options: {
|
function showModal(options: {
|
||||||
action:
|
action:
|
||||||
| "logout-confirm"
|
| "logout-confirm"
|
||||||
@ -361,6 +398,9 @@
|
|||||||
openDocuments = rest;
|
openDocuments = rest;
|
||||||
const { [activeDocumentId]: __, ...savedRest } = savedDocumentContent;
|
const { [activeDocumentId]: __, ...savedRest } = savedDocumentContent;
|
||||||
savedDocumentContent = savedRest;
|
savedDocumentContent = savedRest;
|
||||||
|
documentAccessOrder = documentAccessOrder.filter(
|
||||||
|
(item) => item !== activeDocumentId,
|
||||||
|
);
|
||||||
activeDocumentId = "";
|
activeDocumentId = "";
|
||||||
activeDocumentLabel = "";
|
activeDocumentLabel = "";
|
||||||
editMode = false;
|
editMode = false;
|
||||||
@ -398,6 +438,7 @@
|
|||||||
...savedRest,
|
...savedRest,
|
||||||
[saved.id]: saved.initialContent,
|
[saved.id]: saved.initialContent,
|
||||||
};
|
};
|
||||||
|
touchDocument(saved.id);
|
||||||
activeDocumentId = saved.id;
|
activeDocumentId = saved.id;
|
||||||
activeDocumentLabel = saved.label;
|
activeDocumentLabel = saved.label;
|
||||||
} else {
|
} else {
|
||||||
@ -405,6 +446,7 @@
|
|||||||
...savedDocumentContent,
|
...savedDocumentContent,
|
||||||
[activeDocumentId]: content,
|
[activeDocumentId]: content,
|
||||||
};
|
};
|
||||||
|
touchDocument(activeDocumentId);
|
||||||
}
|
}
|
||||||
} else if (
|
} else if (
|
||||||
selectedSection === "lists" &&
|
selectedSection === "lists" &&
|
||||||
@ -416,7 +458,9 @@
|
|||||||
...savedDocumentContent,
|
...savedDocumentContent,
|
||||||
[activeDocumentId]: content,
|
[activeDocumentId]: content,
|
||||||
};
|
};
|
||||||
|
touchDocument(activeDocumentId);
|
||||||
}
|
}
|
||||||
|
pruneDocumentCache([activeDocumentId]);
|
||||||
} catch {
|
} catch {
|
||||||
// best-effort save
|
// best-effort save
|
||||||
}
|
}
|
||||||
@ -518,11 +562,13 @@
|
|||||||
[resolvedDoc.id]: resolvedDoc.initialContent,
|
[resolvedDoc.id]: resolvedDoc.initialContent,
|
||||||
};
|
};
|
||||||
}
|
}
|
||||||
|
touchDocument(resolvedDoc.id);
|
||||||
savedDocumentContent = {
|
savedDocumentContent = {
|
||||||
...savedDocumentContent,
|
...savedDocumentContent,
|
||||||
[resolvedDoc.id]:
|
[resolvedDoc.id]:
|
||||||
openDocuments[resolvedDoc.id] ?? resolvedDoc.initialContent,
|
openDocuments[resolvedDoc.id] ?? resolvedDoc.initialContent,
|
||||||
};
|
};
|
||||||
|
pruneDocumentCache([resolvedDoc.id]);
|
||||||
activeDocumentId = resolvedDoc.id;
|
activeDocumentId = resolvedDoc.id;
|
||||||
activeDocumentLabel = resolvedDoc.label;
|
activeDocumentLabel = resolvedDoc.label;
|
||||||
}
|
}
|
||||||
@ -540,7 +586,10 @@
|
|||||||
}
|
}
|
||||||
|
|
||||||
function handleDocumentContentChange(content: string) {
|
function handleDocumentContentChange(content: string) {
|
||||||
|
if (!activeDocumentId) return;
|
||||||
openDocuments = { ...openDocuments, [activeDocumentId]: content };
|
openDocuments = { ...openDocuments, [activeDocumentId]: content };
|
||||||
|
touchDocument(activeDocumentId);
|
||||||
|
pruneDocumentCache([activeDocumentId]);
|
||||||
}
|
}
|
||||||
|
|
||||||
async function handleForceSave() {
|
async function handleForceSave() {
|
||||||
@ -552,6 +601,7 @@
|
|||||||
openDocuments = remaining;
|
openDocuments = remaining;
|
||||||
const { [id]: __, ...savedRemaining } = savedDocumentContent;
|
const { [id]: __, ...savedRemaining } = savedDocumentContent;
|
||||||
savedDocumentContent = savedRemaining;
|
savedDocumentContent = savedRemaining;
|
||||||
|
documentAccessOrder = documentAccessOrder.filter((item) => item !== id);
|
||||||
}
|
}
|
||||||
|
|
||||||
async function performDelete(id: string) {
|
async function performDelete(id: string) {
|
||||||
|
|||||||
Loading…
x
Reference in New Issue
Block a user