diff options
| author | Adam Malczewski <[email protected]> | 2026-05-29 13:59:17 +0900 |
|---|---|---|
| committer | Adam Malczewski <[email protected]> | 2026-05-29 13:59:17 +0900 |
| commit | 520c9e30cc58b40d3b1ee9e7895f003c4f873206 (patch) | |
| tree | 7a10da94141d754dca25e728f4a388057a5d5981 /packages/api/src | |
| parent | 0954c6520878e073c7822fc4a8f4a752474f5d7a (diff) | |
| download | dispatch-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.ts | 17 |
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) => { |
