summaryrefslogtreecommitdiffhomepage
path: root/packages/api/src
diff options
context:
space:
mode:
authorAdam Malczewski <[email protected]>2026-05-29 13:59:17 +0900
committerAdam Malczewski <[email protected]>2026-05-29 13:59:17 +0900
commit520c9e30cc58b40d3b1ee9e7895f003c4f873206 (patch)
tree7a10da94141d754dca25e728f4a388057a5d5981 /packages/api/src
parent0954c6520878e073c7822fc4a8f4a752474f5d7a (diff)
downloaddispatch-520c9e30cc58b40d3b1ee9e7895f003c4f873206.tar.gz
dispatch-520c9e30cc58b40d3b1ee9e7895f003c4f873206.zip
feat: disappearing chat history — chunk-limited frontend window with backend pagination
Frontend keeps only a bounded window of chunks in memory (configurable via settings slider, default 100). Older messages are evicted when at the bottom and re-fetched from the backend on scroll-up. - Backend: paginated GET /tabs/:id/messages with ?limit=N&before=seq - Store: evictMessages trims oldest messages until total chunks ≤ limit - Store: loadMoreMessages fetches next page and prepends with dedup - ChatPanel: smart scroll hooks trigger eviction on return-to-bottom - ChatPanel: onNearTop loads older history with scroll-position maintenance - Settings: chunk limit slider in Memory section - Fix: oldestLoadedSeq recalculated after eviction (pagination cursor stays valid) - Fix: seq preserved on ChatMessage for cursor tracking - Fix: scrolledUpTabs cleaned up on tab switch (no memory leak) - Fix: evictMessages reads appSettings.chunkLimit directly (live updates)
Diffstat (limited to 'packages/api/src')
-rw-r--r--packages/api/src/routes/tabs.ts17
1 files changed, 15 insertions, 2 deletions
diff --git a/packages/api/src/routes/tabs.ts b/packages/api/src/routes/tabs.ts
index 6e6734d..afa5735 100644
--- a/packages/api/src/routes/tabs.ts
+++ b/packages/api/src/routes/tabs.ts
@@ -5,6 +5,7 @@ import {
getMessagesForTab,
getSetting,
getTab,
+ getTotalMessageCount,
listOpenTabs,
setSetting,
updateTabModel,
@@ -66,8 +67,20 @@ tabsRoutes.get("/:id", (c) => {
tabsRoutes.get("/:id/messages", (c) => {
const id = c.req.param("id");
- const messages = getMessagesForTab(id);
- return c.json({ messages });
+ const limitRaw = c.req.query("limit");
+ const beforeRaw = c.req.query("before");
+ const limit = limitRaw !== undefined ? Number(limitRaw) : undefined;
+ const before = beforeRaw !== undefined ? Number(beforeRaw) : undefined;
+ const options =
+ limit !== undefined || before !== undefined
+ ? {
+ ...(limit !== undefined && Number.isFinite(limit) ? { limit } : {}),
+ ...(before !== undefined && Number.isFinite(before) ? { before } : {}),
+ }
+ : undefined;
+ const messages = getMessagesForTab(id, options);
+ const total = getTotalMessageCount(id);
+ return c.json({ messages, total });
});
tabsRoutes.patch("/:id", async (c) => {