summaryrefslogtreecommitdiffhomepage
diff options
context:
space:
mode:
authorDax Raad <[email protected]>2026-02-14 13:40:49 -0500
committerDax Raad <[email protected]>2026-02-14 13:41:15 -0500
commit68bb8ce1da922229e6ab4dde4207b431cf9d76a8 (patch)
treea7b8bdf34d7d873a75ea137561851823ff4e4829
parent306fc77076fa3ac0930efefc842e2f61cd5ddd19 (diff)
downloadopencode-68bb8ce1da922229e6ab4dde4207b431cf9d76a8.tar.gz
opencode-68bb8ce1da922229e6ab4dde4207b431cf9d76a8.zip
core: filter sessions at database level to improve session list loading performance
-rw-r--r--packages/opencode/src/server/routes/session.ts14
-rw-r--r--packages/opencode/src/session/index.ts38
2 files changed, 35 insertions, 17 deletions
diff --git a/packages/opencode/src/server/routes/session.ts b/packages/opencode/src/server/routes/session.ts
index 2cf5473f2..1195529e0 100644
--- a/packages/opencode/src/server/routes/session.ts
+++ b/packages/opencode/src/server/routes/session.ts
@@ -53,15 +53,15 @@ export const SessionRoutes = lazy(() =>
),
async (c) => {
const query = c.req.valid("query")
- const term = query.search?.toLowerCase()
const sessions: Session.Info[] = []
- for await (const session of Session.list()) {
- if (query.directory !== undefined && session.directory !== query.directory) continue
- if (query.roots && session.parentID) continue
- if (query.start !== undefined && session.time.updated < query.start) continue
- if (term !== undefined && !session.title.toLowerCase().includes(term)) continue
+ for await (const session of Session.list({
+ directory: query.directory,
+ roots: query.roots,
+ start: query.start,
+ search: query.search,
+ limit: query.limit,
+ })) {
sessions.push(session)
- if (query.limit !== undefined && sessions.length >= query.limit) break
}
return c.json(sessions)
},
diff --git a/packages/opencode/src/session/index.ts b/packages/opencode/src/session/index.ts
index 38007a0a7..255f4dd46 100644
--- a/packages/opencode/src/session/index.ts
+++ b/packages/opencode/src/session/index.ts
@@ -10,7 +10,7 @@ import { Flag } from "../flag/flag"
import { Identifier } from "../id/id"
import { Installation } from "../installation"
-import { Database, NotFoundError, eq, and, or, like } from "../storage/db"
+import { Database, NotFoundError, eq, and, or, gte, isNull, desc, like } from "../storage/db"
import { SessionTable, MessageTable, PartTable } from "./session.sql"
import { Storage } from "@/storage/storage"
import { Log } from "../util/log"
@@ -505,20 +505,38 @@ export namespace Session {
},
)
- export function* list() {
+ export function* list(input?: {
+ directory?: string
+ roots?: boolean
+ start?: number
+ search?: string
+ limit?: number
+ }) {
const project = Instance.project
- // const rel = path.relative(Instance.worktree, Instance.directory)
- // const suffix = path.sep + rel
+ const conditions = [eq(SessionTable.project_id, project.id)]
+
+ if (input?.directory) {
+ conditions.push(eq(SessionTable.directory, input.directory))
+ }
+ if (input?.roots) {
+ conditions.push(isNull(SessionTable.parent_id))
+ }
+ if (input?.start) {
+ conditions.push(gte(SessionTable.time_updated, input.start))
+ }
+ if (input?.search) {
+ conditions.push(like(SessionTable.title, `%${input.search}%`))
+ }
+
+ const limit = input?.limit ?? 100
+
const rows = Database.use((db) =>
db
.select()
.from(SessionTable)
- .where(
- and(
- eq(SessionTable.project_id, project.id),
- // or(eq(SessionTable.directory, Instance.directory), like(SessionTable.directory, `%${suffix}`)),
- ),
- )
+ .where(and(...conditions))
+ .orderBy(desc(SessionTable.time_updated))
+ .limit(limit)
.all(),
)
for (const row of rows) {